2015-05-24 49 views
36

Tôi có bản đồ Map<Type, Long> countByType và tôi muốn có một danh sách đã sắp xếp các từ (tối thiểu đến tối đa) bằng các giá trị tương ứng của chúng. Thử của tôi là:Bản đồ luồng Java 8 vào danh sách các phím được sắp xếp theo giá trị

countByType.entrySet().stream().sorted().collect(Collectors.toList()); 

tuy nhiên điều này chỉ cho tôi danh sách các loại, làm cách nào để có danh sách loại, mà không làm mất thứ tự?

Trả lời

85

Bạn nói rằng bạn muốn sắp xếp theo giá trị, nhưng bạn không có điều đó trong mã của bạn. Vượt qua một lambda (hoặc phương pháp tham khảo) để sorted để cho nó biết làm thế nào bạn muốn sắp xếp.

Và bạn muốn lấy chìa khóa; sử dụng map để chuyển đổi các mục nhập thành khóa.

List<Type> types = countByType.entrySet().stream() 
     .sorted(Comparator.comparing(Map.Entry::getValue)) 
     .map(Map.Entry::getKey) 
     .collect(Collectors.toList()); 
+33

... hoặc '.sorted (Map.Entry.comparingByValue())' –

+0

Sau chaining 'sorted' làm thế nào tôi có thể nhận được dòng trở lại một bản đồ? Về mặt kỹ thuật, tôi biết tôi không thể hoàn nguyên nó về bản đồ vì các bộ của nó không được đặt hàng. Nhưng tôi muốn in bản đồ như thế này '.forEach ((k, v) -> System.out.println (k + ":" + v) 'Làm cách nào tôi có thể đạt được điều này bằng cách sử dụng luồng đó? – dabadaba

+0

@dabadaba sau '.sorted (...)' bạn có một dòng các mục, vì vậy bạn có thể nối thêm '.forEach (e -> System.out.println (e.getKey() +": "+ e.getValue())); ' – Jesper

9

Bạn phải sắp xếp với bộ so sánh tùy chỉnh dựa trên giá trị của mục nhập. Sau đó, chọn tất cả các phím trước khi thu thập

countByType.entrySet() 
      .stream() 
      .sorted((e1, e2) -> e1.getValue().compareTo(e2.getValue())) // custom Comparator 
      .map(e -> e.getKey()) 
      .collect(Collectors.toList()); 
3

Bạn có thể sắp xếp một bản đồ bằng giá trị như dưới đây, nhiều ví dụ here

//Sort a Map by their Value. 
Map<Integer, String> random = new HashMap<Integer, String>(); 

random.put(1,"z"); 
random.put(6,"k"); 
random.put(5,"a"); 
random.put(3,"f"); 
random.put(9,"c"); 

Map<Integer, String> sortedMap = 
     random.entrySet().stream() 
       .sorted(Map.Entry.comparingByValue()) 
       .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, 
         (e1, e2) -> e2, LinkedHashMap::new)); 
System.out.println("Sorted Map: " + Arrays.toString(sortedMap.entrySet().toArray())); 
0

Dưới đây là giải pháp đơn giản với StreamEx

EntryStream.of(countByType).sortedBy(e -> e.getValue()).keys().toList(); 
2
Map<Integer, String> map = new HashMap<>(); 
    map.put(1, "B"); 
    map.put(2, "C"); 
    map.put(3, "D"); 
    map.put(4, "A"); 

    List<String> list = map.values().stream() 
      .sorted() 
      .collect(Collectors.toList()); 

Output: [A, B, C, D]

0

Bạn có thể sử dụng như là một ví dụ về vấn đề của bạn

Map<Integer, String> map = new HashMap<>(); 
    map.put(10, "apple"); 
    map.put(20, "orange"); 
    map.put(30, "banana"); 
    map.put(40, "watermelon"); 
    map.put(50, "dragonfruit"); 

    // split a map into 2 List 
    List<Integer> resultSortedKey = new ArrayList<>(); 
    List<String> resultValues = map.entrySet().stream() 
      //sort a Map by key and stored in resultSortedKey 
      .sorted(Map.Entry.<Integer, String>comparingByKey().reversed()) 
      .peek(e -> resultSortedKey.add(e.getKey())) 
      .map(x -> x.getValue()) 
      // filter banana and return it to resultValues 
      .filter(x -> !"banana".equalsIgnoreCase(x)) 
      .collect(Collectors.toList()); 

    resultSortedKey.forEach(System.out::println); 
    resultValues.forEach(System.out::println); 
Các vấn đề liên quan