我知道Arrays.asList
会创建不可变List
。我的要求是创建不可变的List<Student>
,其中没有null
个元素。所以我先创建new ArrayList()
然后使用java 8 null
删除filters
元素,如下所示:
List<Student> list = new ArrayList<>();
list.add(makeStudent("ram", 'M'));
list.add(makeStudent("sathya", 'F'));
list.add(makeStudent(null, 'M'));
list.add(makeStudent("sri", 'M'));
list = list.stream().filter(s -> s != null).collect(Collectors.toList());
以下是makeStudent
方法,如果名称不可用,则会返回null
:
private Student makeStudent(String name, char gender) {
return null != name ? new Student(name, gender) : null;
}
我认为Collectors.toList()
会创建不可变的。但是我错了。 list
在这里仍然是可变的。有没有更好的方法可以使用list
使null
清除(删除java 8
)并使用单行不可变?
答案 0 :(得分:5)
您可能会将代码重写为此代码:
list = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
收集器collectingAndThen允许您包装结果集合
答案 1 :(得分:1)
即使您指定了Java 8,也可以通过以下方法将现有的List
过滤为完全不可变的 List
,以便您使用Java 9进行查找:
list = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toCollection(List::of));
答案 2 :(得分:0)
使用Collections.unmodifiableList来包装流收集的List
。
list = Collections.unmodifiableList(list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList()));
Collectors.toList()
方法执行诸如reduce:
//pseudo-code
Collectors.reduce(ArrayList::new, List::add, List::addAll)
IF 你传递了一个不可变的List
来减少你不能从流中收集任何项目到List
,因为它是不可变的。
答案 3 :(得分:-1)
您可以按照其他答案中的建议使用Collections.unmodifiableList
,也可以将流转换为数组,然后使用Arrays.asList
。
list = Arrays.asList(list.stream()
.filter(Objects::nonNull)
.toArray(Student[]::new));