针对另一个列表中的项目过滤流 [英] filtering a stream against items in another list

查看:60
本文介绍了针对另一个列表中的项目过滤流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试针对另一个列表中的数据filter流:

trying to filter a stream against data within a different list:

它可以工作,但是我在流的中间使用了for循环.我找不到有关如何将for循环转换为流的任何信息.

It works, but I use a for loop in the middle of the stream. I cannot find any information of how to convert the for loop to a stream.

我可以比.forEach()仅仅.stream() selction.getItems()并拥有一个新的.stream() DATA.accounts,但这是很差的代码,因为它必须在每个.forEach.

I could just .stream() the selction.getItems() than .forEach() and have a new .stream() of DATA.accounts, but that is poor code as it would have to restream on every .forEach.

        y=1;

        DATA.accounts.stream()
            .flatMap(estimate -> estimate.getElements().stream())
            .filter( ele-> {

                // different list;
                for (Element element:selection.getItems()){
                    if (element.getId()==ele.getId()){
                        return true;
                    }
                }
                return false;
            })

            .forEach(element -> {
                element.setDateSchedualed(selectedDate);
                element.setOrder(y);    
                y++;
            });

推荐答案

您可以将filter表示为

.filter(ele -> selection.getItems().stream()
                        .anyMatch(element -> element.getId()==ele.getId())

这个将不得不重播"的事实并不会比原始代码将循环到每个元素的事实困扰您更多.在任何一种情况下,您都创建了具有O(n×m)时间复杂度的操作.如果您可以肯定地预测这些列表之一总是很小,那么这是可以接受的.

The fact that this "would have to restream" shouldn’t bother you more than the fact that the original code will loop for every element. You have created an operation with O(n×m) time complexity in either case. This is acceptable if you can surely predict that one of these lists will always be very small.

否则,无法通过将id值存储在具有快速(最佳情况下为O(1))结构的结构中来准备此操作.即

Otherwise, there is no way around preparing this operation by storing the id values in a structure with a fast (O(1) in the best case) lookup. I.e.

Set<IdType> id = selection.getItems().stream()
    .map(element -> element.getId())
    .collect(Collectors.toSet());

…

.filter(ele -> id.contains(ele.getId())

此外,当y是局部变量时,您的forEach方法显然会增加y变量是一种反模式,甚至无法编译.如果y是一个字段,它将使此代码更糟.在这里,接受临时存储到List

Besides that, your forEach approach incrementing the y variable clearly is an anti-pattern and it doesn’t even compile, when y is a local variable. And if y is a field, it would make this code even worse. Here, it’s much cleaner to accept a temporary storage into a List:

Set<IdType> id = selection.getItems().stream().map(element -> element.getId());

List<ElementType> list = DATA.accounts.stream()
    .flatMap(estimate -> estimate.getElements().stream())
    .filter(ele -> id.contains(ele.getId())
    .collect(Collectors.toList());

IntStream.range(0, list.size())
    .forEach(ix -> {
        ElementType element = list.get(ix);
        element.setDateSchedualed(selectedDate);
        element.setOrder(ix+1);
    });

这篇关于针对另一个列表中的项目过滤流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆