【问题标题】:Java 8 filter to stream list return by methodJava 8过滤器按方法流式返回列表
【发布时间】:2021-09-01 14:59:10
【问题描述】:

我仍在学习java8,但这就是我基本上想要做的事情。我这里有这个方法,我想转换成流。

public void checkCustomers() {

  List<Student> students = studentRegistry.getAllStudents();
  List<Student> mathStudents = new ArrayList<>();
  List<Customer> studentCustomers = new ArrayList<>();

  for (Student student : students) {
       if (!student.getAll().contains(Classes.MATH101)) {
           mathStudents.add(student);
       }
   }

   for (Student student : mathStudents){
       List<Customer> tempStudentCustomers = getCustomers(student.getId());
       studentCustomers.addAll(tempStudentCustomers);
   }

   cancelCustomers(studentCustomers);
}

我已经为此工作了一段时间并且遇到了很多问题。我基本上是在尝试做这样的事情:

cancelCustomers(studentRegistry.getAllStudents().stream()
               .filter(Objects::nonNull)
               .filter(p -> (p.getAll().contains(Classes.MATH101)))
               .collect(Collectors.toList()));

我知道这不起作用的原因有很多,但每次我修复其中一个时,似乎都会弹出一个不同的问题。如有必要,我可以共享其他代码,但我想要做的主要内容在这里。

【问题讨论】:

  • ‍‍cancelCustomers(studentRegistry.getAllStudents().stream().filter(Objects::nonNull). filter(p -&gt; ( p.getAll().contains(Classes.MATH101))). .map(s-&gt;getCustomers(s.getId())).collect(Collectors.toList()));
  • 在我看来问题已经存在于原始代码中,甚至在您开始将其转换为流代码之前。您是否知道循环 for (Student student : mathStudents) { studentCustomers = getCustomers(student.getId()); } 将反复覆盖 studentCustomers 变量,因此只保留最后一个值?
  • 方法getCustomers 是否返回Student 实例的集合,您是否暗示收集所有 个学生客户然后取消它们?同样定义mathStudents的逻辑似乎是倒置的:为什么班级不包含Math101的学生被添加到mathStudents

标签: java java-8 java-stream


【解决方案1】:

试试这个:

studentRegistry.getAllStudents().stream().
               filter(Objects::nonNull).
               filter(p -> ( p.getAll().contains(Classes.MATH101))).
               map(std -> getCustomers(std.getId())). // Maps each student to List<Customer>...
               collect(Collectors.toList())

上面的流代码 sn-p 将返回一个 ListLists。这种形式:List&lt;List&lt;Customer&gt;&gt;.

如果您想将此列表加入到包含所有子元素(客户)的列表中,请将以下内容添加到您的代码中:

List<Customer> studentCustomers = studentRegistry.getAllStudents().stream().
               filter(Objects::nonNull).
               filter(p -> ( p.getAll().contains(Classes.MATH101))).
               map(std -> getCustomers(std.getId())). 
               flatMap(List::stream). // this here does the magic
               collect(Collectors.toList())

但我认为你的函数代码也有问题......

以这部分为例

List<Customer> studentCustomers = new ArrayList<>();


for (Student student : mathStudents){
   studentCustomers = getCustomers(student.getId()); //  You update the array of studentCustomers, but you never do anything with it.
   // You only cancel the customers of the last found mathStudent...
}

cancelCustomers(studentCustomers); // Is this the right logic?

【讨论】:

  • 谢谢 Renis1235。这正是我所需要的。第二个例子,使用 flatMap 效果很好。至于您的 cmets,getCustomers(long student) 返回属于特定学生的所有客户的 ArrayList。在这种情况下,cancelCustomers 预计将为不在 Math101 中的每个学生取消每个客户。我看到逻辑错在哪里了。我应该有一个tempStudentCustomers,分配getCustomers,然后分配studentCustomers.add(tempStudentCustomers)
【解决方案2】:

下面应该可以正常工作。

cancelCustomers(studentRegistrey.getAllStudents().stream()
                .filter(Objects::nonNull)
                .filter(student -> !student.getAll().contains(Classes.MATH101))
                .map(student -> getCustomers(student.getId())
                .collect(Collectors.toList()));

我不确定你是想保留数学学生还是放弃他们。如果您想保留仅数学的学生,请从过滤方法中删除 !

【讨论】:

    【解决方案3】:

    这个怎么样?

    public void checkCustomers() {
        studentRegistry.getAllStudents().stream()
                       .filter(student -> !student.getAll().contains(Classes.MATH101))
                       .map(mathStudent -> getCustomers(mathStudent.getId()))
                       .forEach(this::cancelCustomers);
    }
    

    或者如果您想拨打cancelCustomers() 一次:

    public void checkCustomers() {
        cancelCustomers(studentRegistry.getAllStudents().stream()
                                       .filter(student -> !student.getAll().contains(Classes.MATH101))
                                       .map(mathStudent -> getCustomers(mathStudent.getId()))
                                       .flatMap(List::stream)
                                       .collect(Collectors.toList()));
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-20
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      相关资源
      最近更新 更多