# 如何在同一个流中使用多个过滤器和映射函数？

go评论61阅读模式

How to use multiple filters + map in the same stream?

# 问题

``````List<Integer> Type1ErrorRows = errors.stream()
.filter(c -> (c.getClass() == Type1Error.class))
.map(c -> ((Type1Error) c).getRowNumber())
.collect(Collectors.toList());

List<Integer> Type2ErrorRows = errors.stream()
.filter(c -> (c.getClass() == Type2Error.class))
.map(c -> ((Type2Error) c).getRowNumber())
.collect(Collectors.toList());

List<Integer> mergedRows = Stream.concat(Type1ErrorRows.stream(), Type2ErrorRows.stream())
.collect(Collectors.toList());
``````

How do I merge this to a single stream?

``````    List&lt;Integer&gt; Type1ErrorRows = errors.stream()
.filter(c -&gt; (c.getClass() == Type1Error.class))
.map(c -&gt; ((Type1Error) c).getRowNumber())
.collect(Collectors.toList());

List&lt;Integer&gt; Type2ErrorRows = errors.stream()
.filter(c -&gt; (c.getClass() == Type2Error.class))
.map(c -&gt; ((Type2Error) c).getRowNumber())
.collect(Collectors.toList());
``````

EDIT: Sorry, the question is misleading in this form (really stupid of me), I forgot to mention that I want all the row numbers in a single list as a result:

``````Stream.concat(Type1ErrorRows.stream(), Type2ErrorRows.stream())
.collect(Collectors.toList());
``````

# 答案1

``````public interface ErrorInterface {
int getRowNumber();
}
``````

``````Set<Class<?>> allowedClasses = Set.of(Type1Error.class, Type2Error.class);
List<Integer> rowNumbers = errors.stream()
.filter(err -> allowedClasses.contains(err.getClass()))
.map(err -> (ErrorInterface) err)
.map(ErrorInterface::getRowNumber)
.toList();
``````

I'll assume that a common interface exists, otherwise all the required casting will make it too cumbersome for streams.

``````public interface ErrorInterface {

int getRowNumber();
}
``````

Filter that object's class is allowed, cast, invoke method to get row number.

``````Set&lt;Class&lt;?&gt;&gt; allowedClasses = Set.of(Type1Error.class, Type2Error.class);
List&lt;Integer&gt; rowNumbers = errors.stream()
.filter(err -&gt; allowedClasses.contains(err.getClass()))
.map(err -&gt; (ErrorInterface) err)
.map(ErrorInterface::getRowNumber)
.toList();
``````

# 答案2

``````List<Integer> type1 = new ArrayList<Integer>();
List<Integer> type2 = new ArrayList<Integer>();
for (Error error : errors) {
if (error instanceof Type1Error e1) {
}
else if (error instanceof Type2Error e2) {
}
}
``````

Streams are not the right tool for this job. Just use a loop:

``````List&lt;Integer&gt; type1 = new ArrayList&lt;Integer&gt;();
List&lt;Integer&gt; type2 = new ArrayList&lt;Integer&gt;();
for (Error error : errors) {
if (error instanceof Type1Error e1) {
}
else if (error instanceof Type2Error e2) {
}
}
``````

• 本文由 发表于 2023年8月11日 15:25:19
• 转载请务必保留本文链接：https://go.coder-hub.com/76881472.html
• filter
• java
• stream

go 15

go 14

go 17