我有自己的本地对象StudentInGroup
流(请参见下文),我想用3种几乎相同的方式将其放入地图中。由于某些原因,其中有两个成功,而最后一个引发了异常:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractCollection.add(AbstractCollection.java:262)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
at containers.streams.StreamsTest3.lambda$main$13(StreamsTest3.java:93)
at java.util.HashMap.merge(HashMap.java:1245)
at java.util.stream.Collectors.lambda$toMap$172(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at containers.streams.StreamsTest3.main(StreamsTest3.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
所以对象是:
import java.util.Optional;
public class StudentInGroup {
private Optional<String> groupNumber;
private String name;
private boolean isGirl;
private int age;
@Override
public String toString() {
return "StudentInGroup{" +
"groupNumber=" + groupNumber +
", name='" + name + '\'' +
", isGirl=" + isGirl +
", age=" + age +
'}';
}
public StudentInGroup(String name, String groupNumber, int age, boolean isGirl)
{
this.name=name;
this.groupNumber=Optional.ofNullable(groupNumber);
this.age=age;
this.isGirl=isGirl;
}
public Optional<String> getGroupNumber() {
return groupNumber;
}
public void setGroupNumber(Optional<String> groupNumber) {
this.groupNumber = groupNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isGirl() {
return isGirl;
}
public void setGirl(boolean girl) {
isGirl = girl;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
如果这样创建流:
Optional<StudentInGroup> petrov = Optional.of(new StudentInGroup("Petrov", null, 18, false));
Optional<StudentInGroup> petrova = Optional.of(new StudentInGroup("Petrova", "11-305", 18, true));
List<Optional<StudentInGroup>> studentInGroupList = new ArrayList<>();
studentInGroupList.add(Optional.of(new StudentInGroup("Ivanov", "11-307", 18, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Johns", "11-307", 19, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Walitov", "11-307", 17, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Kowalski", "11-302", 19, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Glauberová", "11-302", 19, true)));
studentInGroupList.add(Optional.of(new StudentInGroup("Dybenko", "11-307", 17, true)));
studentInGroupList.add(Optional.of(new StudentInGroup("Ishikawa", "11-305", 18, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Nguyen", "11-305", 18, false)));
studentInGroupList.add(Optional.of(new StudentInGroup("Chui", "11-305", 18, true)));
studentInGroupList.add(petrov);
studentInGroupList.add(Optional.empty());
studentInGroupList.add(petrova);
Supplier<Stream<StudentInGroup>> studentInGroupStreamSupplier = () -> studentInGroupList.stream().map((o) -> o.orElse(new StudentInGroup(null, null, -1, false)));
和两种工作方法是
Map<Integer, Set<StudentInGroup>> stringStudentInGroupMap3 = studentInGroupStreamSupplier.<StudentInGroup>get().collect(Collectors.toMap(StudentInGroup::getAge, Collections::<StudentInGroup>singleton,
(Set<StudentInGroup> a, Set<StudentInGroup> b) -> {
Set<StudentInGroup> studentInGroupSet = new HashSet<>();
studentInGroupSet.addAll(a);
studentInGroupSet.addAll(b);
return studentInGroupSet;
}));
System.out.println(stringStudentInGroupMap3);
Map<Integer, Set<StudentInGroup>> stringStudentInGroupMap4 = studentInGroupStreamSupplier.<StudentInGroup>get().collect(Collectors.toMap(StudentInGroup::getAge, x -> new HashSet<>(Arrays.asList(x)),
(x, y) -> {
x.addAll(y);
return x;
}));
System.out.println(stringStudentInGroupMap4);
输出值为
{-1=[StudentInGroup{groupNumber=Optional.empty, name='null', isGirl=false, age=-1}], 17=[StudentInGroup{groupNumber=Optional[11-307], name='Dybenko', isGirl=true, age=17}, StudentInGroup{groupNumber=Optional[11-307], name='Walitov', isGirl=false, age=17}], 18=[StudentInGroup{groupNumber=Optional[11-307], name='Ivanov', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional.empty, name='Petrov', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Petrova', isGirl=true, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Nguyen', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Ishikawa', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Chui', isGirl=true, age=18}], 19=[StudentInGroup{groupNumber=Optional[11-302], name='Kowalski', isGirl=false, age=19}, StudentInGroup{groupNumber=Optional[11-302], name='Glauberová', isGirl=true, age=19}, StudentInGroup{groupNumber=Optional[11-307], name='Johns', isGirl=false, age=19}]}
{-1=[StudentInGroup{groupNumber=Optional.empty, name='null', isGirl=false, age=-1}], 17=[StudentInGroup{groupNumber=Optional[11-307], name='Dybenko', isGirl=true, age=17}, StudentInGroup{groupNumber=Optional[11-307], name='Walitov', isGirl=false, age=17}], 18=[StudentInGroup{groupNumber=Optional[11-307], name='Ivanov', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional.empty, name='Petrov', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Petrova', isGirl=true, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Nguyen', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Ishikawa', isGirl=false, age=18}, StudentInGroup{groupNumber=Optional[11-305], name='Chui', isGirl=true, age=18}], 19=[StudentInGroup{groupNumber=Optional[11-302], name='Kowalski', isGirl=false, age=19}, StudentInGroup{groupNumber=Optional[11-302], name='Glauberová', isGirl=true, age=19}, StudentInGroup{groupNumber=Optional[11-307], name='Johns', isGirl=false, age=19}]}
此调用导致上述错误:
Map<Integer, Set<StudentInGroup>> stringStudentInGroupMap6 = studentInGroupStreamSupplier.<StudentInGroup>get().collect(Collectors.toMap(StudentInGroup::getAge, Collections::<StudentInGroup>singleton,
(x, y) -> {
x.addAll(y);
return x;
}));
System.out.println(stringStudentInGroupMap6);
那么,在这种情况下抛出UnsupportedOperationException的原因是什么?
PS。我知道groupingBy
是最好的方法,问题是为什么会引发异常。
答案 0 :(得分:5)
Collections.singleton*()
方法返回不可变的Collection实现。
所以您必须替换:
Collections::<StudentInGroup>singleton
使用:
HashSet::new
或适合您需求的Set
实现。