我是 Java 的新手,我正在尝试以函数式方式编写以下逻辑。
我有一个对象列表,其中有很多字段。 List<someObject>
现在感兴趣的领域是long timestamp
和 String bookType
问题陈述是——我想找到给定列表中具有相同 bookType
的对象的数量。作为具有最低时间戳的那个。
例如,如果我们根据 timestamp
对给定的对象列表进行排序按升序排列,排序列表中的第一个对象有 bookType
字段为 SOMETYPE
;然后我想找出列表中有多少对象 bookType
SOMETYPE
我使用普通的旧非功能性方式编写了这个逻辑,通过维护 2 个临时变量,然后遍历列表一次以找到最低的 timestamp
和相应的bookType
amd 每个 bookType
的计数
但这在 lambda 中运行是 Not Acceptable ,因为它要求变量为 final
我只能编写可以根据 timestamp
对给定列表进行排序的部分
n.stream().sorted(Comparator.comparingLong(someObject::timestamp)).collect(Collectors.toList());
我不知道如何继续查找最低 timestamp
的计数bookType
最佳答案
But this is not acceptable to be run in a lambda, as it requires variables to be final
首先 - 这不是问题,因为您可以将变量设为 Effectively final通过创建例如。单个条目数组并将其单个(第一个)对象传递给 lambda
第二点是,将所有内容都放在一个 lambda 中基本上是没有意义的 - 想一想,如何从逻辑上找到 min
值与计算按某些属性分组的对象相关联? 不是 - 将它(以某种方式)放到一个流中只会混淆您的代码
你应该做什么 - 你应该准备方法来找到 min
值并返回你它的 bookType
然后流式收集并按 bookType
分组并返回具有给定键值的集合的大小
在这个划痕上它可能看起来像:
public class Item {
private final long timestamp;
private final String bookType;
// Constructors, getters etc
}
// ...
public int getSizeOfBookTypeByMinTimestamp() {
return items.stream()
.collect(Collectors.groupingBy(Item::getBookType))
.get(getMin(items))
.size();
}
private String getMin(List<Item> items) {
return items
.stream()
.min(Comparator.comparingLong(Item::getTimestamp))
.orElse( /* HANDLE NO OBJECT */ ) // you can use also orElseThrow etc
.getBookType();
}
关于Java 8 : functional way to write sort, 同时过滤和计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57400074/