Apache Commons CollectionsUtils.select的Java 8 Lambda替换

Cla*_*nei 2 java lambda apache-commons java-8 java-stream

我使用Apache Commons lib有以下代码:

public static List<Address> addressesHasType(final List<Address> addresses, final AddressType... types) {
    return (List<Address>) CollectionUtils.select(addresses, new Predicate() {
        @Override
        public boolean evaluate(final Object object) {
            boolean isContains = false;
            for (int i = 0; i < types.length && !isContains; i++) {
                isContains = ((Address) object).getTypes().contains(types[i]);
            }
            return isContains;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我试图重构它只使用没有Apache Commons lib的lambda和Java 8,如下所示:

List<Address> addressList = addresses.stream()
    .filter(a -> a.getTypes().contains(types)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但这份名单最终变得空洞.我尝试使用findFirst()但它不返回List而是返回Optional对象.

addressList2 = addresses.stream()
    .filter(a -> a.getTypes().contains(types)).findFirst();
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做?

nos*_*sid 7

您的代码中有两个嵌套循环.外循环的转换看起来很好,但转换后的代码中缺少内循环.我们先来看一下内循环:

boolean evaluate(Address address, AddressTypes... types) {
    for (AddressType type : types) {
        if (address.getTypes().contains(type)) {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

使用流和方法引用,实现如下:

boolean evaluate(Address address, AddressTypes... types) {
    return Arrays.stream(types).anyMatch(address.getTypes()::contains);
}
Run Code Online (Sandbox Code Playgroud)

将此转换与您的第一种方法相结合,结果如下所示:

public static List<Address> addressesHasType(List<Address> addresses, AddressType... types) {
    return addresses.stream()
        .filter(a -> Arrays.stream(types).anyMatch(a.getTypes()::contains))
        .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)