Reputation: 43
I have an Map<String,Integer>
and it's sorted by value like this:
set = map.entrySet();
list = new ArrayList<Map.Entry<String, Integer»(set);
Collections.sort( list, (o1, o2) -> (o2.getValue()).compareTo( o1.getValue() ));
I already have a sorted integer list from that map:
word_used = new ArrayList<Integer>(map.values()
.stream()
.sorted()
.collect(Collectors.toList()));
Collections.reverse(word_used);
But how I can get a String list, which will be sorted equal to Map (by value)?
I mean if I have a map with items:
map.put("eggs",1500);
map.put("echo",150);
map.put("foo",320);
map.put("smt",50);
and sort it like:
eggs : 1500
foo : 320
echo : 150
smt : 50
I need to get 2 lists:
eggs
foo
echo
smt
and
1500
320
150
50
Upvotes: 4
Views: 3943
Reputation: 5256
You can use a TreeMap with a comparator that compares values rather than keys, and then just call keys() and values() on that.
See: https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
Upvotes: 0
Reputation: 727057
You can add projection to your streams using map()
, like this:
List<String> word_used = map.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<String,Integer>::getValue).reversed())
.map(Map.Entry<String,Integer>::getKey)
.collect(Collectors.toList());
List<Integer> ints_used = map.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<String,Integer>::getValue).reversed())
.map(Map.Entry<String,Integer>::getValue)
.collect(Collectors.toList());
Note that this approach sorts twice. You can capture the entries once, and then project from that temporary list, like this:
List<Map.Entry<String,Integer>> sortedList = map
.entrySet()
.stream()
.sorted(Comparator.comparing(Map.Entry<String,Integer>::getValue).reversed())
.collect(Collectors.toList());
List<String> word_used = sortedList
.stream()
.map(Map.Entry<String,Integer>::getKey)
.collect(Collectors.toList());
List<Integer> ints_used = sortedList
.stream()
.map(Map.Entry<String,Integer>::getValue)
.collect(Collectors.toList());
Upvotes: 3
Reputation: 6491
One might sort and iterate only once using this method:
List<String> word_used = new ArrayList<String>();
List<Integer> ints_used = map.entrySet().stream()
.sorted(Comparator.comparing(Map.Entry<String,Integer>::getValue).reversed())
.peek(e -> word_used.add(e.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
Upvotes: 0
Reputation: 181734
You already have a List
(referenced by variable list
) of the map Entry
s, sorted by value into the order you describe. You can just construct new, separate List
s of the keys and values from those objects. The non-stream version of that might be:
List<String> words = new ArrayList<>();
List<Integer> values = new ArrayList<>();
for (Map.Entry<String, Integer> entry : list) {
words.add(entry.getKey());
values.add(entry.getValue());
}
Upvotes: 2