【问题标题】:Java Stream Object ElementsJava 流对象元素
【发布时间】:2018-04-06 02:16:44
【问题描述】:

我有一个代码块需要从 c# 转换为 java

public List<Student> getListWithSameStudentSet() {
    return(StudentManager.studentList.ToList().FindAll(m =>
        m.listID != this.listID
        m.studentList.Except(this.studentList).Count() == 0)); 
}

我的尝试如下:

List<UUID> checklist = stream(StudentManager.studentList).select(m -> m.getstudentList()).first();
checklist.removeAll(this.studentList);
return(stream(ApplianceDataManager.signatureList).where(m ->
    m.getListID() != this.listID &&
    checklist.size() == 0)).toList();

我知道.first() 流没有执行FindAll。我有什么选择可以得到FindAll.Except

提前通知:我的设备使用KitKatAPI level 19

【问题讨论】:

  • 这不是 Java Stream API。除此之外,您应该认识到checklist是否为空在整个操作过程中都不会改变,因此对每个元素重复它是没有意义的(因此它甚至与原始代码的逻辑不匹配)。但是m.studentList.Except(this.studentList).Count() == 0背后的逻辑是什么? this.studentList.containsAll(m.studentList) 的一种非常低效的说法?
  • @Holger 大声喊叫或至少短路m.studentList.Except(this.studentList).Take(1).Count() == 0!m.studentList.Except(this.studentList).Take(1).Any()

标签: java c# android java-stream


【解决方案1】:

重构 C# 代码。

虽然这个问题主要关注在Java 中找到与C# 版本等效的代码,但我想指出一些您可以改进的地方。

理想情况下,您希望利用 deferred execution 并且仅在需要时执行 LINQ 查询

即尝试尽可能晚地执行查询。因此,你的方法应该变成:

public IEnumerable<Student> GetListWithSameStudentSet() {
    return StudentManager.studentList
                         .Where(m => m.listID != this.listID &&
                            !m.studentList.Except(this.studentList)
                                          .Take(1)//short circuit
                                          .Any()
                         ); 
}

现在这意味着即使你调用了这个方法,也不会执行任何操作;相反,它在您枚举返回的IEnumerable 或调用急切操作时执行,在这种情况下,您有兴趣将IEnumerable 元素转换为 List 实例.

所有,你需要做的就是在你调用方法的时候这样做:

var students = GetListWithSameStudentSet().ToList(); // execution begins here

使用 Streams API 将 C# 代码转换为 Java

您当前编写的内容绝对不是使用流 API。而你想要的是这个:

public List<Student> getListWithSameStudentSet() {
     return StudentManager.studentList
                          .filter(m -> m.listId != this.listID &&
                                  this.studentList.containsAll(m.studentList))
                          .collect(Collectors.toList());
}

或者如果你想返回一个Stream&lt;T&gt; 来模拟IEnumerable&lt;T&gt;C# 版本中的返回值,那么你可以这样做:

public Stream<Student> getListWithSameStudentSet() {
         return StudentManager.studentList
                              .filter(m -> m.listId != this.listID &&
                                      this.studentList.containsAll(m.studentList))
                              );
}

在不使用 Streams API 的情况下将 C# 代码转换为 Java

public List<Student> getListWithSameStudentSet() {
       List<Student> accumulator = new ArrayList<>();
       for(Student student : StudentManager.studentList){
           if(student.listId != this.listID &&
                   this.studentList.containsAll(student.studentList)){
                accumulator.add(student);
           }
       }
       return accumulator;
}

【讨论】:

    猜你喜欢
    • 2018-03-06
    • 1970-01-01
    • 2023-01-10
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    相关资源
    最近更新 更多