1

This problem is related to This SO question

I have an instances of Student class.

class Student {
    String name;
    String addr;
    String type;

    public Student(String name, String addr, String type) {
        super();
        this.name = name;
        this.addr = addr;
        this.type = type;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", addr=" + addr + "]";
    }

    public String getName() {
        return name;
    }

    public String getAddr() {
        return addr;
    }
}

And I have a code to create a map , where it store the student name as the key and some processed addr values (a List since we have multiple addr values for the same student) as the value.

public class FilterId {

    public static String getNum(String s) {
        // should do some complex stuff, just for testing
        return s.split(" ")[1];
    }

    public static void main(String[] args) {
        List<Student> list = new ArrayList<Student>();
        list.add(new Student("a", "test 1", "type 1"));
        list.add(new Student("a", "test 1", "type 2"));
        list.add(new Student("b", "test 1", "type 1"));
        list.add(new Student("c", "test 1", "type 1"));
        list.add(new Student("b", "test 1", "type 1"));
        list.add(new Student("a", "test 1", "type 1"));
        list.add(new Student("c", "test 3", "type 2"));
        list.add(new Student("a", "test 2", "type 1"));
        list.add(new Student("b", "test 2", "type 1"));
        list.add(new Student("a", "test 3", "type 3"));
        list.add(new Student("a", "my test 4", "type 1"));
        Map<String, List<String>> map = new HashMap<>();
    }
}

I can have a code like below to get an out put like this. {a=[1, 2, 3], b=[1, 2], c=[1, 3]}

Map<String, Set<String>> map = list.stream()
.collect(Collectors.groupingBy(
    Student::getName,
    Collectors.mapping(student -> getNum(student.getAddr()),
        Collectors.toSet())));

But how can we add an extra checks to this,

like, if the type is type 3, then that entry should not go to the Set for that student ,

And add another constraint check to getNum like,

    public static String getNum(String s) {
        // should do some complex stuff, just for testing
        if(s.contains("my")) {
            return "";
        } else {
            return s.split(" ")[1];
        }
    }

And I don't need to add that empty string to the set associated with that Student.

So the expected output for that case will be, {a=[1, 2], b=[1, 2], c=[1, 3]} Since a's test 3 is type 3 one. And the a's my test 4 is also not considered since it fails the check as well.

How can I achive this target with Java 8 streams.

2 Answers 2

1

Simply insert the filter() call before starting the grouping (with the Predicate of your choice):

Map<String, Set<String>> map = list.stream()
  .filter(s -> !s.type.equals("type 3"))
  .collect(Collectors.groupingBy(
    Student::getName,
    Collectors.mapping(student -> getNum(student.getAddr()), Collectors.toSet())));

Result: {a=[1, 2, test], b=[1, 2], c=[1, 3]}

Sign up to request clarification or add additional context in comments.

2 Comments

What about the other condition, So that the output will be {a=[1, 2], b=[1, 2], c=[1, 3]} (without the test element for a)
@prime you expand the Predicate in the filter call - I thought that the question was more about where to put the filter call and not how to write the predicate
1

This should be good for all of requirements and no need to have getNum method:

Map< String, Set<String> > map = list.stream()
.filter( s -> !Objects.equals( s.getType(), "type 3") )
.filter( s -> !s.getAddr().contains("my") )
.collect( Collectors.groupingBy( Student::getName, 
          Collectors.mapping( s -> s.getAddr().split(" ")[1], Collectors.toSet() ) ) );

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.