Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
找出Java8流过滤器是否过滤了某些内容的优雅方法_Java_Java 8_Java Stream - Fatal编程技术网

找出Java8流过滤器是否过滤了某些内容的优雅方法

找出Java8流过滤器是否过滤了某些内容的优雅方法,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个从数据库中获取的项目的列表 我会这样做: List<Item> list; list.stream() .filter( i -> i.condition() ) .mapToLong( Item::asLong ) .sum() ; 列表; list.stream() .filter(i->i.condition()) .mapToLong(项目::asLong) .sum() ; 现在我想知道,过滤器是否过滤掉了一些东西,这样我就

我有一个从数据库中获取的
项目的
列表

我会这样做:

List<Item> list;
list.stream()
    .filter( i -> i.condition() )
    .mapToLong( Item::asLong )
    .sum()
    ;
列表;
list.stream()
.filter(i->i.condition())
.mapToLong(项目::asLong)
.sum()
;
现在我想知道,过滤器是否过滤掉了一些东西,这样我就可以从不再需要的数据库中删除这些东西

我可以做到:

List<Item> list2 = list.stream()
    .filter( i -> i.condition() )
    .collect( Collectors.toList() )
    ;

int theSizeIWant = list2.size();

list2.stream().mapToLong( Item::asLong )
     .sum()
     ;
List list2=List.stream()
.filter(i->i.condition())
.collect(收集器.toList())
;
int theSizeIWant=list2.size();
list2.stream().mapToLong(项::asLong)
.sum()
;

但是我想知道是否有一种更优雅的解决方案不需要创建中间列表。

是的,您可以这样做

Map<Boolean, List<Item>> partitions =
    list.stream.collect(Collectors.partitioningBy(i -> i.condition()));
映射分区=
list.stream.collect(收集器.partitioningBy(i->i.condition());

其中
partitions.get(true)
将为您提供好的分区,而
partitions.get(false)
将为您提供要删除的分区。

一个可能的解决方案是使用谓词对流进行分区并求和值。分区是用。在这种情况下,谓词将是您的筛选函数,而下游收集器将是对值求和

public static void main(String[] args) {
    List<Item> list = new ArrayList<>();
    Map<Boolean, Long> map = 
        list.stream()
            .collect(Collectors.partitioningBy(
                Item::condition, 
                Collectors.summingLong(Item::asLong)
            ));
    long sumWithTrueCondition = map.get(true);
    long sumWithFalseCondition = map.get(false);
}
publicstaticvoidmain(字符串[]args){
列表=新的ArrayList();
地图=
list.stream()
.collect(收集器(
项目::条件,
收集器.summingLong(项::asLong)
));
long-sumWithTrueCondition=map.get(true);
long-sumWithFalseCondition=map.get(false);
}
映射将包含谓词为
true
(resp.
false
)且带有
true
键(resp.
false
)的和


这样,如果已过滤某些内容,
sumWithTrueCondition
将严格大于0。此外,您可以通过添加
sumWithTrueCondition
sumWithFalseCondition

来获得总和。另一种解决方案是计算lambda表达式中的坏元素:

List<String> strings = Arrays.asList("1", "2", "3", "12", "4", "5");
List<String> badOnes = new ArrayList<>();

strings.stream()
       .filter(s -> {
         boolean returnValue = !s.contains("1");
         if (!returnValue) {
           badOnes.add(s);
         }
         return returnValue;
       })
       .forEach(s -> System.out.println(s));

System.out.println(badOnes);
List strings=Arrays.asList(“1”、“2”、“3”、“12”、“4”、“5”);
List badOnes=new ArrayList();
strings.stream()
.过滤器(s->{
布尔返回值=!s.contains(“1”);
if(!returnValue){
坏人。添加(s);
}
返回值;
})
.forEach->System.out.println;
系统输出打印项次(坏项次);

这减轻了中间列表的负担,但仍然需要进行第二次计算。如果某个东西没有通过条件,它就不会在流的下游传递,也不会被计数

int count = 0;
count必须是一个实例变量,然后您可以执行以下操作:

List<Item> list;
list.stream()
    .filter( i -> i.condition() )
    .mapToLong( (item) -> { count++; return item.asLong(); } )
    .sum();

boolean isFiltered = list.size() > count;
列表;
list.stream()
.filter(i->i.condition())
.mapToLong((项)->{count++;return item.asLong();})
.sum();
布尔值isFiltered=list.size()>count;

list2.size()在第二个代码片段中是奇怪的
for()
loop是优雅的…:)注意,这里有状态过滤器。这违反了
过滤器
的约定。您对
坏人的写入在这里不是线程安全的!这是一个即将发生的事故。使用线程安全的构造,如设置一个
原子布尔值
。实际上,@Tunaki,filter参数不是有状态的,也没有干扰,因为它写入的状态没有用作流管道使用的任何计算的输入。但是,它仍然是错误的,因为它有副作用,而且副作用不是线程安全的。@BrianGoetz您能解释一下为什么这里要求线程安全吗?这不是只有在使用并行流时才会引起关注吗?@kingds,这要看情况而定。这有点像说“如果炉子上没有油布,把油布放在炉子上是安全的。”这是真的,但是。。。这仍然是一个相当不负责任的举动。您是否绝对肯定,在未来20年的代码维护中,不会有人试图将流并行化?你愿意把公司的生意押在这上面吗?正如我之前的评论所说,这是一个(很容易避免的)即将发生的事故。当然,只要你再也不碰它,它可能没问题,但这真的描述了软件在现实世界中是如何维护的吗?