5

I have a simple map and need to create a list that is sorted based on the number in ascending order from a given list:

Map auto = new HashMap();
auto.put("Merc", 3);
auto.put("Citroen", 5);
auto.put("Opel", 10);
auto.put("BMW", 20);

List<String> given = new ArrayList<>();
given.add("Opel");
given.add("BMW");
given.add("Citroen");

So the given list needs to be sorted so that it will be in this order: Citroen, Opel, BMW. Was thinking of:

  1. create another map then iterate through list
  2. get number from first map
  3. put the number as the key and the name as value in the new map
  4. sort the map by key
  5. iterate threw new map then add values to the list

This seems terrible :/, any suggestions and perhaps better data structures to use?

Mercury
  • 711
  • 1
  • 11
  • 21

5 Answers5

8

Using Java 8 you can do.

Map<String, Integer> auto = new HashMap<>();
auto.put("Merc", 3);
auto.put("Citroen", 5);
auto.put("Opel", 10);
auto.put("BMW", 20);

List<String> given = new ArrayList<>();
given.add("Opel");
given.add("BMW");
given.add("Citroen");

// to sort the selected elements.
given.sort(Comparator.comparing(auto::get));

// to sort all elements.
List<String> names = auto.entrySet().stream()
        .sorted(Comparator.comparing(Map.Entry::getValue))
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());

Breaking this down

List<String> names = 
         // give the set of entries as a Stream.
         auto.entrySet().stream()
        // sort these entries, using the field returned by getValue()
        .sorted(Comparator.comparing(Map.Entry::getValue))
        // now sorted, turn each Entry into just the getKey()
        .map(Map.Entry::getKey)
        // now we have a stream of keys, turn this into a List<String>
        .collect(Collectors.toList());
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
5

Collections#sort

Collections.sort(given, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return auto.get(o1).compareTo(auto.get(o2));
    }
});

Or with lambda:

Collections.sort(given, (o1, o2) -> auto.get(o1).compareTo(auto.get(o2)));

Java 8 null-safe solution inspired from multiple answers

given.sort(Comparator.comparing((s) -> auto.getOrDefault(s, Integer.MAX_VALUE)));
Volune
  • 4,324
  • 22
  • 23
3

With Java 8, you could just do

given.sort(Comparator.comparing(auto::get));

...and it's just that one-liner. Or with the Guava library you could do

Collections.sort(given, Ordering.natural().onResultOf(Functions.forMap(auto)));
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • can you explain little? – Kick Buttowski Aug 18 '14 at 20:21
  • 2
    To explain, [Comparator.comparing](http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparing-java.util.function.Function-) creates a Comparator implementation that applies the given function to each element and compares the results. In this case, `auto::get` will take a string from the list and return the number it's mapped to in `auto`, so the list will be sorted by these corresponding numbers. – Sean Van Gorder Aug 18 '14 at 20:34
0

Create a Car class that implements Comparable and includes the name and priority.

Then you can sort lists with Collections.sort() directly.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0
Map<String,Integer> auto = new HashMap<String,Integer>();
auto.put("Merc", 3);
auto.put("Citroen", 5);
auto.put("Opel", 10);
auto.put("BMW", 20);

Set<Map.Entry<String,Integer>> set = auto.entrySet();
List<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(set);
Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){

             @Override
            public int compare(Entry<String, Integer> o1,
                    Entry<String, Integer> o2) {

                return o1.getValue().compareTo(o2.getValue());
            }
});

Once you have List Objects of Map.Entry,you can extract key using Entry.getKey()

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
  • Entry doesn't have a `compareTo` method. – Peter Lawrey Aug 18 '14 at 20:31
  • It implies that `given` is a map, but the question state that both are distinct (eg: a map and list). Also, while the question does not state it, the map may not have duplicate values while the list may. – NoDataFound Aug 18 '14 at 20:58