Java 8を使用しようとしていますStream
s を使用して 内の要素を検索しますLinkedList
。ただし、フィルター条件に一致するものが 1 つだけであることを保証する必要があります。
次のコードを見てください:
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;
}
}
このコードは、User
ID に基づいて を検索します。ただし、User
フィルターに一致する の数については保証されません。
フィルター ラインを次のように変更します。
User match = users.stream().filter((user) -> user.getId() < 0).findAny().get();
投げますよNoSuchElementException
(良い!)
ただし、複数の一致がある場合はエラーをスローするようにしたいと思います。これを行う方法はありますか?
ベストアンサー1
カスタムを作成する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
に
List
コレクターと一緒にオブジェクトを収集しますCollectors.toList()
。- 最後に追加のフィニッシャーを適用して、単一の要素を返すか、
IllegalStateException
ifをスローしますlist.size != 1
。
使用されます:
User resultUser = users.stream()
.filter(user -> user.getId() > 0)
.collect(toSingleton());
Collector
その後、コンストラクターで例外を引数として渡したり、2 つの値を許可するように調整するなど、必要に応じてこれをカスタマイズできます。
代わりの(おそらくあまりエレガントではない)解決策:
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);