![](/img/trans.png)
[英]Modifying the returned Map value type with collectors.groupingBy in Java stream
[英]Java8: About order of Map elements returned by Collectors.groupingBy
希望就從示例中修改的以下代碼尋求建議。
我想知道更改輸入List元素序列時,結果Map中的輸出序列是否會改變。 但是,似乎輸出在所有情況下都是相同的(我在IDE上反復運行了該程序)。 我是否可以就是否可以預期生成的Map元素的順序尋求建議? 使用枚舉或字符串時,順序(字母/非字母順序)會有所區別嗎,還是元素順序只是隨機的?
public class TestCountry {
public enum Continent {ASIA, EUROPE}
String name;
Continent region;
public TestCountry (String na, Continent reg) {
name = na;
region = reg;
}
public String getName () {
return name;
}
public Continent getRegion () {
return region;
}
public static void main(String[] args) {
List<TestCountry> couList1 = Arrays.asList (
new TestCountry ("Japan", TestCountry.Continent.ASIA),
new TestCountry ("Italy", TestCountry.Continent.EUROPE),
new TestCountry ("Germany", TestCountry.Continent.EUROPE));
List<TestCountry> couList2 = Arrays.asList (
new TestCountry ("Italy", TestCountry.Continent.EUROPE),
new TestCountry ("Japan", TestCountry.Continent.ASIA),
new TestCountry ("Germany", TestCountry.Continent.EUROPE));
Map<TestCountry.Continent, List<String>> mapWithRegionAsKey1 = couList1.stream ()
.collect(Collectors.groupingBy (TestCountry ::getRegion,
Collectors.mapping(TestCountry::getName, Collectors.toList())));
Map<String, List<Continent>> mapWithNameAsKey1 = couList1.stream ()
.collect(Collectors.groupingBy (TestCountry::getName,
Collectors.mapping(TestCountry::getRegion, Collectors.toList())));
Map<TestCountry.Continent, List<String>> mapWithRegionAsKey2 = couList2.stream ()
.collect(Collectors.groupingBy (TestCountry ::getRegion,
Collectors.mapping(TestCountry::getName, Collectors.toList())));
Map<String, List<Continent>> mapWithNameAsKey2 = couList2.stream ()
.collect(Collectors.groupingBy (TestCountry::getName,
Collectors.mapping(TestCountry::getRegion, Collectors.toList())));
System.out.println("Value of mapWithRegionAsKey1 in couList1: " + mapWithRegionAsKey1);
System.out.println("Value of mapWithNameAsKey1 in couList1: " + mapWithNameAsKey1);
System.out.println("Value of mapWithRegionAsKey2 in couList2: " + mapWithRegionAsKey2);
System.out.println("Value of mapWithNameAsKey2 in couList2: " + mapWithNameAsKey2);
}
}
/*
* Output:
Value of mapWithRegionAsKey1 in couList1: {ASIA=[Japan], EUROPE=[Italy,
Germany]}
Value of mapWithNameAsKey1 in couList1: {Japan=[ASIA], Italy=[EUROPE],
Germany=[EUROPE]}
Value of mapWithRegionAsKey2 in couList2: {ASIA=[Japan], EUROPE=[Italy,
Germany]}
Value of mapWithNameAsKey2 in couList2: {Japan=[ASIA], Italy=[EUROPE],
Germany=[EUROPE]}
*/
Collectors.groupingBy()
當前返回一個HashMap
。 這是一個實現細節,可以在將來的版本中更改。
HashMap
的條目未排序,但是它們的迭代順序(在打印HashMap
)是確定性的,並且不取決於插入順序。
因此,無論輸入List
元素的順序如何,您都會看到相同的輸出。 但是,您不應該依賴該順序,因為它是實現細節。
如果您關心輸出Map
條目的順序,則可以修改代碼以生成LinkedHashMap
(默認順序為插入順序)或TreeMap
(對鍵進行排序)。
順便說一句,如果您將輸入更改為
List<TestCountry> couList1 = Arrays.asList (
new TestCountry ("Japan", TestCountry.Continent.ASIA),
new TestCountry ("Italy", TestCountry.Continent.EUROPE),
new TestCountry ("Germany", TestCountry.Continent.EUROPE));
List<TestCountry> couList2 = Arrays.asList (
new TestCountry ("Germany", TestCountry.Continent.EUROPE),
new TestCountry ("Italy", TestCountry.Continent.EUROPE),
new TestCountry ("Japan", TestCountry.Continent.ASIA)
);
您將在輸出中得到不同的順序:
couList1中mapWithRegionAsKey1的值:{ASIA = [Japan],EUROPE = [ Italy,Germany ]}
couList1中mapWithNameAsKey1的值:{Japan = [ASIA],意大利= [EUROPE],德國= [EUROPE]}
couList2中mapWithRegionAsKey2的值:{ASIA = [Japan],EUROPE = [ Germany,Italy ]}
couList2中mapWithNameAsKey2的值:{Japan = [ASIA],意大利= [EUROPE],德國= [EUROPE]}
這是由於各個輸出List
的元素(在當前實現中為ArrayList
)是根據插入順序進行排序的,這取決於輸入List
的順序。
在質疑之前,請閱讀說明以下內容的文檔:
不保證返回的Map或List對象的類型 ,可變性,可序列化性或線程安全性。
因此,如果您無法確定返回的地圖類型,就無法真正確定將返回的順序(如果有)。 好吧, 正如Eran指出的那樣,它是一個HashMap
,但這不能保證。
問題是您為什么要介意呢? 如果是出於學術目的,那么就有意義,如果不是,那就收集一些可以保證訂單的東西。
Collectors.groupingBy
采用一個參數,可讓您指定您可能需要的實際Map
實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.