2017-09-08 17 views
4

我想按特定的順序排序其中一個字段的流。排序Java流像開關條件

現在,我通過轉換流列出,並使用一個開關,然後重新加入他們到一個列表中所需的順序實現這一目標。

 

    fruits.forEach(fruit -> { 
       switch (fruit.getName()) { 
        case "Orange": 
         orangesList.add(fruit); 
         break; 
        case "Apple": 
         applesList.add(fruit); 
         break; 
        case "WaterMelon": 
         watermelonList.add(fruit); 
         break; 
        default: 
         otherFruits.add(fruit); 
         break; 
       } 
    }); 

    genericFruitList.addAll(0, orangeList); 
    genericFruitList.addAll(1, applesList); 
    genericFruitList.addAll(2, watermelonList); 
    genericFruitList.addAll(3, otherFruits); 

我不知道是否有任何的改變來實現這一使用流分類方法 和使用自定義的比較器或類似的東西。

在此先感謝。

+4

'Collectors.groupingBy(Fruit :: getName)'會按照名稱對水果進行分組,如同在交換機中一樣。然後你可以這樣做addAll。 –

+0

創建一個幫助程序類可能會給你適當的列表:fruitHelper.getList(fruit.getName) –

+3

請注意,您目前的邏輯很奇怪。假設你有兩種水果:你的結果'genericFruitList'將是'橙子,蘋果,西瓜,其他,西瓜,蘋果,橙子'。你的意思是指定插入點,還是隻打算在最後添加它們? –

回答

6

您可以使用一個明確的順序一樣

List<String> order = Arrays.asList("Orange", "Apple", "WaterMelon"); 
Comparator<String> comp 
    = Comparator.comparingInt(name -> order.indexOf(name)-Integer.MIN_VALUE); 

可以b創建一個比較È使用像

List<Fruit> genericFruitList = fruits 
    .sorted(Comparator.comparing(fruit -> fruit.getName(), comp)) 
    .collect(Collectors.toList()); 

然而,排序整個列表,特別是與一個List.indexOf基於比較,可以安靜低效的。另一種方法是

List<Fruit> genericFruitList = fruits 
    .collect(Collectors.groupingBy(fruit -> fruit.getName())) 
    .entrySet().stream() 
    .sorted(Map.Entry.comparingByKey(comp)) 
    .flatMap(e -> e.getValue().stream()) 
    .collect(Collectors.toList()); 

剛剛執行每Fruit和僅排序的不同映射的哈希查找。

這可以被看作是Bucket Sort的變體。

+0

非常感謝。這對我來說非常合適:) – Antonio682

5

如果要排序的水果放入一個特定的順序(橘子,再蘋果,然後西瓜,然後選擇「其他」),你可以這樣定義一個比較:

List<String> order = Arrays.asList("Orange", "Apple", "Watermelon"); 
Comparator<Fruit> comparator = Comparator.comparing(f -> { 
    int i = order.indexOf(f.getName()); 
    return (i >= 0) ? i : order.size(); 
}); 

,然後排序:

List<Fruit> genericFruitList = fruits.stream().sorted(comparator).collect(Collectors.toList()); 
+0

順便說一句番石榴有'Ordering.explicit(名單)''也可以在這裏使用。 – Eugene

+1

@Eugene [「如果你使用的是Java 8,這個類是現在已經過時」(https://google.github.io/guava/releases/23.0/api/docs/com/google/common/collect/Ordering。 HTML)。另外,這不處理「其他」值。 –