gpt4 book ai didi

java - 将 Java Stream 过滤为 1 个且仅 1 个元素

转载 作者:搜寻专家 更新时间:2023-11-01 00:55:19 26 4
gpt4 key购买 nike

我正在尝试使用 Java 8 Stream s 在 LinkedList 中查找元素。但是,我想保证只有一个匹配过滤条件。

拿这段代码:

public static void main(String[] args) {

LinkedList<User> users = new LinkedList<>();
users.add(new User(1, "User1"));
users.add(new User(2, "User2"));
users.add(new User(3, "User3"));

User match = users.stream().filter((user) -> user.getId() == 1).findAny().get();
System.out.println(match.toString());
}

static class User {

@Override
public String toString() {
return id + " - " + username;
}

int id;
String username;

public User() {
}

public User(int id, String username) {
this.id = id;
this.username = username;
}

public void setUsername(String username) {
this.username = username;
}

public void setId(int id) {
this.id = id;
}

public String getUsername() {
return username;
}

public int getId() {
return id;
}
}

这段代码根据他们的 ID 找到一个 User。但无法保证有多少 User 匹配过滤器。

将过滤器行更改为:

User match = users.stream().filter((user) -> user.getId() < 0).findAny().get();

将抛出一个NoSuchElementException(很好!)

不过,如果有多个匹配项,我希望它抛出一个错误。有办法做到这一点吗?

最佳答案

创建自定义 Collector

public static <T> Collector<T, ?, T> toSingleton() {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.size() != 1) {
throw new IllegalStateException();
}
return list.get(0);
}
);
}

我们使用 Collectors.collectingAndThen通过

构建我们想要的 Collector
  1. 使用 Collectors.toList() 收集器将我们的对象收集到 List 中。
  2. 在最后应用一个额外的终结器,返回单个元素——或者如果 list.size != 1 则抛出一个 IllegalStateException

用作:

User resultUser = users.stream()
.filter(user -> user.getId() > 0)
.collect(toSingleton());

然后您可以根据需要自定义此 Collector,例如将异常作为构造函数中的参数,调整它以允许两个值,等等。

另一种——可以说不太优雅——的解决方案:

您可以使用涉及 peek()AtomicInteger 的“解决方法”,但实际上您不应该使用它。

你可以做的只是将它收集在一个 List 中,就像这样:

LinkedList<User> users = new LinkedList<>();
users.add(new User(1, "User1"));
users.add(new User(2, "User2"));
users.add(new User(3, "User3"));
List<User> resultUserList = users.stream()
.filter(user -> user.getId() == 1)
.collect(Collectors.toList());
if (resultUserList.size() != 1) {
throw new IllegalStateException();
}
User resultUser = resultUserList.get(0);

关于java - 将 Java Stream 过滤为 1 个且仅 1 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34822079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com