Java8-省略繁琐的collect方法

Java8-省略繁琐的collect方法,java,java-8,java-stream,Java,Java 8,Java Stream,Java8流api是一个非常好的特性,我非常喜欢它。让我紧张的一件事是,90%的时间我都希望输入作为集合,输出作为集合。结果是我必须一直调用stream()和collect()方法: collection.stream().filter(p->p.isCorrect()).collect(Collectors.toList()); 是否有任何java api允许我跳过流并直接对集合进行操作(如c#中的linq): 是的,使用: 删除此集合中满足给定谓词的所有元素 请注意,它将更改给定集合

Java8流api是一个非常好的特性,我非常喜欢它。让我紧张的一件事是,90%的时间我都希望输入作为集合,输出作为集合。结果是我必须一直调用
stream()
collect()
方法:

collection.stream().filter(p->p.isCorrect()).collect(Collectors.toList());
是否有任何java api允许我跳过流并直接对集合进行操作(如c#中的
linq
):

是的,使用:

删除此集合中满足给定谓词的所有元素

请注意,它将更改给定集合,而不是返回新集合。但您可以创建集合的副本并对其进行修改。还要注意,谓词需要被否定才能充当过滤器:

public static <E> Collection<E> getFilteredCollection(Collection<E> unfiltered,
                                                      Predicate<? super E> filter) {
    List<E> copyList = new ArrayList<>(unfiltered);

    // removeIf takes the negation of filter 
    copyList.removeIf(e -> { return !filter.test(e);});  

    return copyList;
}

如果不需要修改原始集合,需要过滤视图,请考虑番石榴。

< P>流有一个定义良好的体系结构。在你开始这条路之前,你可能想了解一下

但是为什么不实现一个集合,它实现了一个类似的流接口,为您封装代码

public class StreamableCollection implements Collection, Stream {
...
}
然后你可以为你的用例做一些复杂的假设。您仍然可以从collections接口打开一个流,但是您也可以直接跳入,然后在该接口的内部处理流的打开

    streamableCollection cs = new streamableCollection();
    cs.filter();
    cs.stream();
您的IDE将帮助您实现所有功能。。。只需将所有内容传递回默认实现。

您可能喜欢使用


这样做的好处是,在保持不可变的同时,可以稍微简短一些。

如果您想对集合进行操作,这是一种可行的方法

示例(获取10位首批vip客户的id):


你可以试试这个,从番石榴图书馆。它似乎比流式方法稍微少了一点混乱

 ImmutableList.copyOf(Iterables.filter(collection, MyClass::isCorrect));

有关该技术的讨论,请参阅。

我也认为流API很好,但对于短操作来说,它很冗长。我在几个项目中使用了这些实用方法:

import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Functions {

    public static <T,V> List<V> map(final List<T> in, final Function<T, V> function) {
        return in == null ? null : map(in.stream(), function);
    }

    public static <T,V> List<V> map(final Stream<T> in, final Function<T, V> function) {
        return in == null ? null : in
            .map(function)
            .collect(Collectors.toList());
    }

    public static <T> List<T> filter(final List<T> in, final Predicate<T> predicate) {
        return in == null ? null : filter(in.stream(), predicate);
    }

    public static <T> List<T> filter(final Stream<T> in, final Predicate<T> predicate) {
        return in == null ? null : in
            .filter(predicate)
            .collect(Collectors.toList());
    }
}
import java.util.List;
导入java.util.function.function;
导入java.util.function.Predicate;
导入java.util.stream.collector;
导入java.util.stream.stream;
公共类功能{
公共静态列表映射(最终列表输入,最终功能){
返回in==null?null:map(in.stream(),函数);
}
公共静态列表映射(最终流输入、最终函数){
返回in==null?null:in
.map(函数)
.collect(Collectors.toList());
}
公共静态列表过滤器(中的最终列表,最终谓词){
返回in==null?null:filter(in.stream(),谓词);
}
公共静态列表筛选器(最终流输入、最终谓词){
返回in==null?null:in
.filter(谓词)
.collect(Collectors.toList());
}
}
这让我可以做

List<String> wrapped = Functions.map(myList, each -> "[" + each + "]");
List wrapped=Functions.map(myList,each->“[”+each+“]);

通常我也会静态导入该方法。

是的,有几个库可以解决Java8的流冗余问题。不完整的列表:

我更喜欢乔。我在上一个项目中一直在使用它。其他的我知道,但我没有真正使用,所以我不能给你一个印象

您与jOOL的示例如下:

Seq.seq(collection).filter(p->p.isCorrect()).toList();

如果您愿意使用第三方库,您可以使用在集合下直接提供丰富API的库。您的示例可以使用Eclipse集合编写如下

collection.select(p->p.isCorrect)
collection.select(MyClass::isCorrect)
注意:我是Eclipse集合的提交者。

您有很多选择

collection.select(p->p.isCorrect)
collection.select(MyClass::isCorrect)
我们可以利用延迟的扩展集合

  CollectionX<String> collection = ListX.of("hello","world");
  CollectionX<String> filtered = collection.filter(p->p.isCorrect());

[披露我是cyclops react的首席开发人员]

请记住,谓词是否定的(与
filter
相比),
removeIf
修改原始集合,而不返回新集合。
copyList.removeIf(filter.negate())
可能有兴趣知道,从Java 9中,您将能够执行
collection.stream().collect(过滤(p->p.isCorrect(),toList())
。这不是收集器的真正目的,但我想我宁愿使用它,也不愿创建方法。@Jean FrançoisSavard,这比
collection.stream().filter更好吗(p->p.isCorrect()).collect(toList())
?当您将操作隐藏在实用程序方法ala
getFilteredCollection
中时,使用
removeIf
没有任何意义,因为您可以简单地说
返回未过滤的.stream().filter(filter).collect(collector.toList());
对调用者没有区别。而且它比先复制整个列表,然后删除项目更短、更高效。我认为您需要一个定义
流()的
可流化的
接口
方法,并实现它,而不是
。它类似于
Iterable
迭代器
的比较。
迭代器
都是消耗的,不可重用的,因此
*能够的
接口可以通过为每次想要再次运行它时定义工厂方法来解决这个问题。
StreamableCollection
如何处理
过滤器
?如果它修改了基础集合,那就是一个问题。如果它不修改,那就是一个视图,那就是一个问题。我不相信你能明智地实现它。当然,这是一个快速的概念@HankD。好主意,肯定会清理模式。@Boristeider我想这就是为什么treams并不像OP想要的那样实现。你可以为它们的用例拼凑一些东西,但我不确定这是否是一个好主意。我本来想提到StreamEx,但在本例中它提供的东西很少。它提供了一个更接近C#API的
API,这可能是OP正在搜索的。@user3364192注意这一点显然不同。
filter()
返回一个
视图
,因此
Pr
Seq.seq(collection).filter(p->p.isCorrect()).toList();
collection.select(p->p.isCorrect)
collection.select(MyClass::isCorrect)
  CollectionX<String> collection = ListX.of("hello","world");
  CollectionX<String> filtered = collection.filter(p->p.isCorrect());
  ReactiveSeq.fromIterable(collection)
             .filter(p->p.isCorrect())
             .toList();