Java8 Stream上的Call Filter方法

时间:2017-09-20 19:01:24

标签: java spring java-8

是否可以更新Stream数据并直接返回?我想更新消费者发送的请求参数的流数据,请参阅下面的代码。

Supplier<Stream<User>> userStream = users::stream;

userStream.get().filter(user -> user.getRole().getType().getName().equalsIgnoreCase(value));
userStream.get().filter(user -> user.getDownloadCertificate() == check );

2 个答案:

答案 0 :(得分:3)

您无法更新Stream,因为它不是数据结构,而是支持顺序和并行聚合操作的一系列元素(来源:https://docs.oracle.com/javase/8/docs/api/?java/util/stream/Stream.html)。

Java 8文档解释了Streams和Collections之间的主要区别:

  

收藏品溪流虽然有一些肤浅的相似之处,却有不同的目标。馆藏主要关注其元素的有效管理和访问。相反,流不提供直接访问或操纵其元素的手段,而是涉及声明性地描述它们的源以及将在该源上聚合执行的计算操作。但是,如果提供的流操作不提供所需的功能,则BaseStream.iterator()BaseStream.spliterator()操作可用于执行受控遍历。

     

流管道(如上面的“小部件”示例)可以视为流源上的查询。除非源是为并发修改而明确设计的(例如ConcurrentHashMap),否则在查询流源时可能会导致不可预测或错误的行为。

     

来源:https://docs.oracle.com/javase/8/docs/api/?java/util/stream/Stream.html

您案例中所需的Stream用法可能如下所示:

List<User> users = getUsers(); // let's assume this method returns a list of users
String name = "some name";
boolean check = true;

//Now let's create a new list of filtered users
List<User> filteredUsers = users.stream()
        .filter(user -> user.getRole().getType().getName().equalsIgnoreCase(name))
        .filter(user -> user.getDownloadCertificate() == check)
        .collect(Collectors.toList());

请记住,未修改初始用户列表。当终端操作(.collect)被调用时,流迭代一次。

答案 1 :(得分:2)

Stream将迭代数据源以执行它所代表的操作,但永远不会修改源。

如果您想要就地修改源集合,只需直接执行它而不需要任何流:

users.removeIf(user -> !user.getRole().getType().getName().equalsIgnoreCase(value));
users.removeIf(user -> user.getDownloadCertificate() != check );

当然,这要求users是一个可变集合。如果情况并非如此,则无论如何都必须创建新的集合,在这种情况下,您可以使用Stream API创建新集合,如this answer所示。