简体   繁体   English

转换列表时过滤出值 <SomeObject> 到地图 <String, Set<String> &gt;使用Java 8流API

[英]Filter out values when converting List<SomeObject> to Map<String, Set<String>> using Java 8 streams API

This problem is related to This SO question 这个问题涉及到这个问题的SO

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. 我有一个代码来创建地图,在其中存储学生姓名作为键,并存储一些处理过的addr值(一个List,因为我们为同一个学生提供了多个addr值)。

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 , 例如, 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, 并向getNum添加另一个约束检查,

    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. 而且我不需要将该空字符串添加到与该Student关联的set中。

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. 因此,在这种情况下的预期输出将为{a=[1, 2], b=[1, 2], c=[1, 3]}因为atest 3type 3 And the a 's my test 4 is also not considered since it fails the check as well. 并且a也是my test 4因为它也未通过检查。

How can I achive this target with Java 8 streams. 如何使用Java 8流实现此目标。

Simply insert the filter() call before starting the grouping (with the Predicate of your choice): 只需在开始分组之前插入filter()调用即可(使用您选择的Predicate ):

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]} 结果: {a=[1, 2, test], b=[1, 2], c=[1, 3]}

This should be good for all of requirements and no need to have getNum method: 这对所有要求都应该是好的,并且不需要getNum方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 筛选清单 <Map<String, String> &gt;使用流 - Filter List<Map<String, String>> using streams 过滤器 Map <string,list<object> &gt; 使用 Java 流</string,list<object> - Filter Map<String,List<Object>> Using Java Streams 使用Java 8流API创建String映射和排序列表 - Create a map of String and sorted list using Java 8 streams API 将List转换<A>为Map</a> <String,List<A> <A>&gt;使用java 8流API</a> - converting List<A> to Map<String,List<A>> using java 8 stream API 如何转换地图<String, List<String> &gt; 设置<String>使用流? - How to convert Map<String, List<String>> to Set<String> using streams? Java 8流,将对象列表转换为Map <String, Set<String> &gt; - Java 8 streams, convert List of object to Map<String, Set<String>> 转换清单 <E> 到地图 <String, List<String> &gt;使用Java 8流 - convert List<E> to Map<String, List<String>> using java 8 streams 转换集合列表<string>设置<string>使用 JAVA 8 个流</string></string> - Convert List of Set<String> to Set<String> using JAVA 8 Streams 使用Java 8流,如何转换Map <String, Map<String, List<Person> &gt;&gt;到地图 <Integer, Map<String, Integer> &gt;? - Using Java 8 streams, how to transform Map<String, Map<String, List<Person>>> to Map<Integer, Map<String, Integer>>? 使用Java Streams使用过滤器将对象列表转换为字符串列表 - Convert List of Objects to List of String with filter using Java Streams
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM