使用java stream,我有一个ClassA列表,应用于流以进行过滤,所以使用List。stream()。过滤器(谓词)。这样,谓词就需要ClassA的谓词来应用,但我真的想要String的谓词,因为ClassA。Field1是字符串类型。因此,与其让谓词包含f-
缺少的链接是什么,我需要如何转换流才能做到这一点?
对于其他上下文,在过滤之后,我需要从过滤列表中提取第二个字段,因此目标是拥有ClassA。第二场。val(例如,假设我需要提取一个与该项目名称关联的项目ID,所以我按名称过滤)
另外:这是一个简化,实际需要的是使用startswith,而不是equals。
您需要将从类中提取字符串和过滤这些字符串的逻辑分开:
public class StringFieldPredicate<T> implements Predicate<T> {
private final Function<T, String> extractStringFunction;
private final Predicate<String> stringPredicate;
public StringFieldPredicate(Function<T, String> extractStringFunction, Predicate<String> stringPredicate) {
this.extractStringFunction = extractStringFunction;
this.stringPredicate = stringPredicate;
}
@Override
public boolean test(T t) {
return stringPredicate.test(extractStringFunction.apply(t));
}
}
它可以这样使用:
public static void main(String[] args) {
List<Number> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream().filter(new StringFieldPredicate<>(Number::toString, it -> it.startsWith("1")));
}
受@bedrin帖子的启发,这里提供了一种不需要新课程的方法
假设你有这样的课程:
class ClassA {
String name;
//getter, setter ..
}
class ClassB {
String name;
//getter, setter ..
}
和列表,例如:
List<ClassA> myAs = List.of(new ClassA("myA_1"), new ClassA("myA_1"), new ClassA("myA_42"));
List<ClassB> myBs = List.of(new ClassB("myB_1"), new ClassB("myB_9"), new ClassB("myB_33"));
然后,您可以编写一个方法,该方法接受字段提取器函数和要测试的字符串:
private static <T> Predicate<T> nameEquals( Function<? super T, ?> fieldExtractor, String toTestAgainst ) {
return t -> toTestAgainst.equals(fieldExtractor.apply(t));
}
并使用上述方法筛选列表。用法示例:
myAs.stream().filter(nameEquals(ClassA::getName, "myA_1")).forEach(System.out::println);
myBs.stream().filter(nameEquals(ClassB::getName, "myB_1")).forEach(System.out::println);
映射流本身的建议通常会导致丢失所需的实际类。相反,请应用一个精简的转换包装:
listOfA.stream()
.filter(a -> sharedPredicate.test(a.getField1()))
...
问题内容: 是否存在Java 8流操作来限制(可能是无限的)直到第一个元素与谓词不匹配? 在Java 9中,我们可以使用下面的示例来打印所有小于10的数字。 由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么? 问题答案: 操作并已添加到JDK9。你的示例代码 在JDK 9下编译和运行时,其行为将完全符合你的预期。 JDK 9已发布。可在此处下载:http : //jdk.java
问题内容: 是否存在Java 8流操作来限制(可能是无限的)Stream直到第一个元素与谓词不匹配? 在Java 9中,我们可以takeWhile像下面的示例那样使用它来打印所有小于10的数字。 由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么? 问题答案: 这样的操作在Java 8中应该是可能的,但不一定能有效地完成-例如,您不必并行化这样的操作,因为您必须按顺序查看元素。 该
问题内容: 我想做类似的事情: Python的标准库中是否有类似行为? 我知道在这里自己动手很容易,但是我正在寻找一种更标准的方法。 问题答案: 您可以使用filter方法: 或列表理解: 要查找单个元素,可以尝试: 尽管如果没有匹配项将引发异常,因此您可能希望将其包装在try / catch中。方括号()使之成为生成器表达式,而不是列表理解。 就我个人而言,尽管我只是使用常规的过滤器/理解并采用
有两个具有相同结构的地图,即map1和map2,其结构为
问题内容: 我无法编译它,甚至可以链接谓词lambda吗? 或唯一的方法是显式创建一个谓词,然后像这样组合: 还是有更多的“功能优雅”的方式来实现同一目标? 问题答案: 您 可以 使用: 但这不是很优雅。如果要直接指定条件,则只需使用一个λ: