Java 8:同时编写排序,过滤和计数的功能方法

dip*_*ang 5 java functional-programming java-8 java-stream

我是Java的新手,我正在尝试以功能性方式编写以下逻辑。

我有一个对象列表,其中有很多字段。List<someObject> 现在感兴趣的领域是long timestampString bookType

问题陈述是-我想找到给定列表中bookType与时间戳最少的对象数量相同的对象数。

例如,如果我们基于timestamp升序对给定的对象列表进行排序,并且排序后的列表中的第一个对象的bookType字段为SOMETYPE;;然后我想找出列表中有多少个对象bookType SOMETYPE

我使用普通的旧非功能性方法编写了此逻辑,方法是维护2个temp变量,然后遍历列表一次,以找到最低值timestamp和相应的bookTypeamd计数bookType

但这不能在lambda中运行,因为它需要将变量 final

我只能写我可以根据给定列表排序的部分 timestamp

n.stream().sorted(Comparator.comparingLong(someObject::timestamp)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我被困在如何继续寻找最低计数 timestamp bookType

m.a*_*icz 7

但这不能在lambda中运行,因为它需要变量为最终变量

首先-这不是问题,因为您可以通过创建eg 来使变量有效最终。单入口数组并将其单个(第一个)对象传递给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();
}
Run Code Online (Sandbox Code Playgroud)