簡體   English   中英

比較器,用於按頻率排序,而不創建比較器實現類

[英]Comparator for sorting by frequency without Creating a Comparator implementation class

只是想知道我們是否可以在不編寫Custom Comparator類的情況下使用Java 8根據重復數字的頻率對List進行排序。

我需要根據給定的整數頻率和自然數值順序對其進行排序。

我在Comparator.naturalOrder()時出錯

這是我嘗試的代碼:

Integer[] given = new Integer[]{0,0,1,22,11,22,22,11,44,555,55,66,77,88,99};
List<Integer> intList = Arrays.asList(given);


Map<Integer, Long> frequencyMap = intList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<Integer> newList = intList.stream().sorted(Comparator.comparing(frequencyMap::get).thenComparing(Comparator.naturalOrder())).collect(Collectors.toList());
System.out.println(newList.toString());

預期的輸出是

[1, 44, 55, 66, 77, 88, 99, 555, 0, 0, 11, 11, 22, 22, 22]

PS:在第一行中使用數組,以避免在多行中使用list.add()並獲得清晰的理解。

不幸的是,當用thenComparing(Comparator.naturalOrder())鏈接Comparator.comparing(frequencyMap::get)時,Java的類型推斷無法識別比較對象的類型。 由於Map.get的方法簽名為get(Object) ,因此編譯器將Comparator<Object>推斷為Comparator.comparing(frequencyMap::get)結果類型。

您可以通過插入顯式類型來解決此問題。 但是請注意,您不是在使用collect(Collectors.toList())的結果,而只是打印未受影響的原始List 另一方面,給出數組時,您不需要List

Integer[] given = {0,0,1,22,11,22,22,11,44,555,55,66,77,88,99};

Map<Integer, Long> frequencyMap = Arrays.stream(given)
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Arrays.sort(given,
    Comparator.<Integer>comparingLong(frequencyMap::get)
       .thenComparing(Comparator.naturalOrder()));

System.out.println(Arrays.toString(given));

對於不更改陣列的打印,您也可以使用以下替代方法

Arrays.stream(given)
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet().stream()
    .sorted(Map.Entry.<Integer, Long>comparingByValue()
        .thenComparing(Map.Entry.comparingByKey()))
    .flatMap(e -> LongStream.range(0, e.getValue()).mapToObj(l -> e.getKey()))
    .forEach(System.out::println);

這將對組進行排序,而不是對單個值進行排序,並按計數的頻率打印相同的值。

您需要添加一個類型見證者,較小的編譯器弱點:

 intList.stream()
        .sorted(Comparator.comparing((Integer x) -> frequencyMap.get(x))
                          .thenComparing(Comparator.naturalOrder()))
        .forEachOrdered(System.out::println);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM