Java8:About collector.groupingBy返回的映射元素的顺序
我想就下面一段从遇到的示例中修改的代码寻求建议 我想知道当输入列表元素序列改变时,结果映射中的输出序列是否会改变。然而,似乎所有情况下的输出都是相同的(我已经在IDE上反复运行了这个程序)。我是否可以就生成的地图元素的顺序征求意见? 当使用枚举或字符串时,序列(字母/非字母?)是否会有任何差异,或者元素序列只是随机的Java8:About collector.groupingBy返回的映射元素的顺序,java,list,java-8,java-stream,collectors,Java,List,Java 8,Java Stream,Collectors,我想就下面一段从遇到的示例中修改的代码寻求建议 我想知道当输入列表元素序列改变时,结果映射中的输出序列是否会改变。然而,似乎所有情况下的输出都是相同的(我已经在IDE上反复运行了这个程序)。我是否可以就生成的地图元素的顺序征求意见? 当使用枚举或字符串时,序列(字母/非字母?)是否会有任何差异,或者元素序列只是随机的 public class TestCountry { public enum Continent {ASIA, EUROPE} String name;
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]}
*/
公共类TestCountry{
公共枚举大陆{亚洲、欧洲}
字符串名;
大陆区域;
公共测试国家(字符串na,大陆注册){
name=na;
region=reg;
}
公共字符串getName(){
返回名称;
}
公共区域(){
返回区;
}
公共静态void main(字符串[]args){
List couList1=Arrays.asList(
新试验国(“日本”,试验国。大陆。亚洲),
新试验国(“意大利”,试验国。大陆。欧洲),
新试验国(“德国”,试验国。大陆。欧洲));
List couList2=Arrays.asList(
新试验国(“意大利”,试验国。大陆。欧洲),
新试验国(“日本”,试验国。大陆。亚洲),
新试验国(“德国”,试验国。大陆。欧洲));
Map mapWithRegionAsKey1=couList1.stream()
.collect(Collectors.groupingBy(TestCountry::getRegion),
Collectors.mapping(TestCountry::getName,Collectors.toList());
Map mapWithNameAsKey1=couList1.stream()
.collect(Collectors.groupingBy(TestCountry::getName、,
Collectors.mapping(TestCountry::getRegion,Collectors.toList());
Map mapWithRegionAsKey2=couList2.stream()
.collect(Collectors.groupingBy(TestCountry::getRegion),
Collectors.mapping(TestCountry::getName,Collectors.toList());
Map mapWithNameAsKey2=couList2.stream()
.collect(Collectors.groupingBy(TestCountry::getName、,
Collectors.mapping(TestCountry::getRegion,Collectors.toList());
System.out.println(“列表1中mapWithRegionAsKey1的值:“+mapWithRegionAsKey1”);
System.out.println(“couList1中mapWithNameAsKey1的值:“+mapWithNameAsKey1”);
System.out.println(“列表2中mapWithRegionAsKey2的值:“+mapWithRegionAsKey2”);
System.out.println(“couList2中mapWithNameAsKey2的值:“+mapWithNameAsKey2”);
}
}
/*
*输出:
mapWithRegionAsKey1在列表1中的值:{亚洲=[日本],欧洲=[意大利,
德国]}
couList1中mapWithNameAsKey1的值:{日本=[亚洲],意大利=[欧洲],
德国=[欧洲]}
mapWithRegionAsKey2在couList2中的值:{亚洲=[日本],欧洲=[意大利,
德国]}
couList2中mapWithNameAsKey2的值:{日本=[亚洲],意大利=[欧洲],
德国=[欧洲]}
*/
收集器。groupingBy()
当前返回一个HashMap
。这是一个可以在未来版本中更改的实现细节
HashMap
的条目没有排序,但是它们的迭代顺序(在打印HashMap
时)是确定的,并且不依赖于插入顺序
因此,无论输入列表中元素的顺序如何,您都可以看到相同的输出。但是,您不应该依赖于该顺序,因为它是一个实现细节
如果您关心输出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)
);
List couList1=Arrays.asList(
新试验国(“日本”,试验国。大陆。亚洲),
新试验国(“意大利”,试验国。大陆。欧洲),
新试验国(“德国”,试验国。大陆。欧洲));
List couList2=Arrays.asList(
新测试国家(“德国”,测试国家。大陆。欧洲),
新试验国(“意大利”,试验国。大陆。欧洲),
新测试国家(“日本”,测试国家。大陆。亚洲)
);
您将在输出中获得不同的顺序:
mapWithRegionAsKey1在列表1中的值:{亚洲=[日本],欧洲=[意大利,德国]}
couList1中mapWithNameAsKey1的值:{日本=[亚洲]、意大利=[欧洲]、德国=[欧洲]}
mapWithRegionAsKey2在couList2中的价值:{亚洲=[日本],欧洲=[德国,意大利]}
couList2中mapWithNameAsKey2的值:{日本=[亚洲]、意大利=[欧洲]、德国=[欧洲]}
这是因为单个输出列表
的元素(在当前实现中是ArrayList
s)是根据插入顺序排序的,插入顺序取决于输入的顺序列表
,对此提出疑问之前,请阅读说明如下的文档:
对于返回的映射或列表对象的类型、可变性、可序列化性或线程安全性没有任何保证
所以,若你们不知道返回的是哪种类型的映射,你们就不知道会有什么顺序(若有的话)。目前,它是一个HashMap
,但这并不能保证
问题是你为什么会在乎这个?如果它是为了学术目的,它是有意义的,如果不是的话,收集到一些确实能保证秩序的东西
collector.groupingBy
获取一个参数,该参数允许您指定可能需要的实际Map
实现 另见…@Holger数字…:)