为了账号安全,请及时绑定邮箱和手机立即绑定

具有已知界限的 Java Stream 最小值

具有已知界限的 Java Stream 最小值

紫衣仙女 2023-07-19 16:49:47
我有一个列表流,我想获取其中元素最少的条目。我当然可以做类似的事情Stream<List<T>> s = ...s.min((e1, e2) -> e1.size() - e2.size());但在这种情况下,我们知道最小值的下界,因为大小是非负的。这意味着当找到大小为 0 的列表时,我们实际上可以停止,而不是也遍历列表的其余部分。使用 Java Streams 可以以一种不错的方式实现这一点吗?我想象它看起来像这样,给出一个比较器和一个函数,告诉我们当前最小值何时是全局最小值:s.boundedMin(    (e1, e2) -> e1.size() - e2.size(),    e -> e.size() == 0)我想不出一种方法来实现这一点。当然,我可以只使用 Iterable 并使用带有break语句的循环来实现这一点,我只是想知道流是否也可以让我到达那里。编辑:为了让它更清楚一点。该流可能包含也可能不包含大小为 0 的列表。我的问题是 min() 将遍历整个流,即使它已经找到大小为 0 的列表(它已经尽可能小了)。因此,我正在寻找的是min 的实现,它不需要通过提供最小值的下界来扫描整个流。Edit2:没有流的等效迭代解决方案是List<List<T>> s = ...List<T> min = null;for (List<T> l : s) {        if (min == null || min.size() > l.size())            min = l;        if (min.size() == 0) {            break;        }}
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

就是图个好玩儿:


static <T> int size(Stream<List<T>> st) {


    class MinHolder implements Consumer<List<T>> {


        private int min = Integer.MAX_VALUE;


        public void accept(List<T> l) {

            if (min > l.size()) {

                min = l.size();

            }

        }

    }


    MinHolder holder = new MinHolder();

    Spliterator<List<T>> sp = st.spliterator();


    int elements = 0;

    for (; sp.tryAdvance(holder) && holder.min > 0; ++elements) {


    }


    System.out.printf("took %s elements to find the min%n", elements);

    return holder.min;

}

以及一些测试用例:


public static void main(String[] args) {

    Stream<List<Integer>> st = Stream.of(List.of());

    System.out.println(size(st));


    st = Stream.empty();

    System.out.println(size(st));


    st = Stream.of(List.of(), List.of(1), List.of(1, 2), List.of(1, 2, 3));

    System.out.println(size(st));

}

如果你不是被迫使用 a,Stream<List<T>>那么就不要使用;这种条件中断并不是 Streams 的设计初衷,许多人会认为这是一种滥用。


查看完整回答
反对 回复 2023-07-19
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信