简体   繁体   中英

Java 8 Lambda Replacement for Apache Commons CollectionsUtils.select

I have the following code using 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;
        }
    });
}

I trying to make to refactor it to use only lambda and Java 8 without Apache Commons lib, something like this:

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

But the list become empty in the end. I tried using findFirst() to but it does not returns a List but a Optional object.

addressList2 = addresses.stream()
    .filter(a -> a.getTypes().contains(types)).findFirst();

How I can do this?

You have two nested loops in your code. The transformation of the outer loop looks good, but the inner loop is missing in the transformed code. Let's take a look at the inner loop first:

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

Using a stream and a method reference, the implementation looks as follows:

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

Combining this transformation with your first approach, the result looks as follows:

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());
}

Your first predicate uses contains(types[i]) . Your second uses contains(types) .

So they don't do the same thing at all. The second predicate checks that the types contains the array of AddressType types , instead of checking that it contains one of the elements of the array of AddressType types .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM