Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort list based on priority from a map

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?

like image 812
Mercury Avatar asked Aug 18 '14 20:08

Mercury


3 Answers

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());
like image 72
Peter Lawrey Avatar answered Oct 06 '22 01:10

Peter Lawrey


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)));
like image 44
Volune Avatar answered Oct 05 '22 23:10

Volune


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)));
like image 33
Louis Wasserman Avatar answered Oct 06 '22 00:10

Louis Wasserman