0

The question is simple and can be done in thousand of ways. But since I am learning Java 8, I would like to do it in the Java 8 way.

I have two list of strings, ex:

List<String> list1 = Arrays.asList("A", "B", "C", "D");
List<String> list2 = Arrays.asList("A", "D", "E");

I want to take the first element from list1 and check if the string is present in list2 and produce a Map<Boolean, String>. Something like this:

Map<Boolean, String> resultMap = list1.stream().collect(partial -> Collectors.partitioningBy(list2.stream().filter(existing -> matchString(partial, existing))));

private static boolean matchString(String partial, String existing) {
    return partial.equals(existing);
}

The above code has a compilation error at matchString(partial, existing):

Wrong 1st argument type. Found: '', required: 'java.lang.String'

Few things to note is that, the in my actual scenario it's not a simple list of string but a more complicated object and that object doesn't override equals or hashcode method.

I very well know that this can be done in different ways. But could somebody please let me know how do we use Collectors.partitioningBy in this particular scenario.

2
  • 2
    You haven't explained what the Map<Boolean, String> represents. All we have is a snippet of code that doesn't compile. Commented Mar 14, 2019 at 21:10
  • What @shmosel said: What the mapping is to represent is unclear. As written, the mapping would have at most two elements, True mapped to a string value and False mapped to a string value. I'm guessing that the mapping is intended to answer whether a particular value of the first list is a member of the second list, in which case at the very least the mapping should be typed as Map<String, Boolean>. Commented Mar 14, 2019 at 21:16

2 Answers 2

4

With Collectors.partitioningBy you can get Map<Boolean, List<String>>. From partitioningBy doc:

Returns a Collector which partitions the input elements according to a Predicate, and organizes them into a Map<Boolean, List<T>>.

In your case:

Map<Boolean, List<String>> map = list1.stream()
            .collect(Collectors.partitioningBy(list2::contains));

In case of more complex object that doesn't override equals/hashcode you can do comparison by some specific field. Assuming you have something like:

class ComplexObj {
    private String id;
    ...
}

Map<Boolean, List<ComplexObj>> map = list1.stream()
            .collect(Collectors.partitioningBy(obj -> list2.stream()
                    .map(ComplexObj::getId)
                    .anyMatch(id -> id.equals(obj.getId()))));
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, but `contains' wont work because hashcode and equals are not overriden
@RahulDevMishra your question says you have two lists of String. If you actually have objects without proper hashCode/equals implementations, you should include that into your question, resp. you should not talk about strings in the first place.
1

Find my implementation below using Collectors.partitioningBy. I use List.contains() method for predicate and it works fine. Kindly try and share feedback/suggestions. Thanks.

package net.javapedia.streams;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PartitioningByEx1 {

    public static void main(String[] args) {

        List<String> list1 = Arrays.asList("A", "B", "C", "D");
        List<String> list2 = Arrays.asList("A", "D", "E");

        list1.stream().collect(Collectors.partitioningBy(item -> list2.contains(item)))
                .forEach((key, val) -> System.out.println(key + "-->>" + val));
    }

}

Program output:

Output

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.