yma*_*ros 10 java lambda java-8
是否有任何方法(方法,lambda或优雅构造)基于给定的比较器在列表中查找元素?
我写了一个像这样的方法:
private static <T> boolean contains(List<T> list, T item, Comparator<? super T> comparator) {
return list.stream()
.anyMatch(listItem -> comparator.compare(listItem, item) == 0
);
}
Run Code Online (Sandbox Code Playgroud)
但我希望用更优雅的东西来代替它.
我不想添加任何依赖项,所以没有Guava,"commons"等等.我真的在Java 8中寻找一种非常好的方法.
编辑:我认为更优雅的一些例子(这是使用代码):
// sadly, this method doesn't exist
// nor is there a static one in Collections
// but maybe you can think of another way?
if (list.containsSame(item, comparator)) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
据我所知,没有直接解决此任务的内置功能.因此,您无法避免创建实用程序方法(如果您希望减少代码重复),那么值得考虑哪种实用方法在其他方案中也很有用.
例如,如果是我的项目,我知道几乎总有一些方法可以让部分功能应用飞来飞去,比如:
public static <T,U,R> Function<U,R> bind(BiFunction<T,U,R> f, T t) {
return u -> f.apply(t, u);
}
Run Code Online (Sandbox Code Playgroud)
利用这种现有方法,解决方案可能如下所示:
static <T> boolean contains(List<T> list, T item, Comparator<? super T> comparator) {
return list.stream().map(bind(comparator::compare, item))
.anyMatch(Predicate.isEqual(0));
}
Run Code Online (Sandbox Code Playgroud)
但这不一定是最好的解决方案.
另一种方法可以是具有用于将a Comparator
转换为等式BiPredicate
的方法和用于部分应用的实用方法BiPredicate
:
public static <T> BiPredicate<T,T> match(Comparator<T> f) {
return (a,b)->f.compare(a, b)==0;
}
public static <T,U> Predicate<U> bind(BiPredicate<T,U> f, T t) {
return u -> f.test(t, u);
}
Run Code Online (Sandbox Code Playgroud)
然后contains
方法变得如此简单
static <T> boolean contains(List<T> list, T item, Comparator<? super T> comparator) {
return list.stream().anyMatch(bind(match(comparator), item));
}
Run Code Online (Sandbox Code Playgroud)
但是,如果实用程序方法也可以在项目的其他位置使用,那么这只是一种简化.另一方面,它们具有如下通用性质,可以default
在后续Java版本中将类似方法作为方法添加到函数接口中.在这种情况下,使用此类实用程序方法的代码已准备好迁移到该较新版本.
不确定这是否是您想要的,但一种可能性是创建您自己的接口扩展Stream
并提供您想要的方法(注意:未经测试):
public interface MyStream<R>
extends Stream<R>
{
// Yay! Static methods in interfaces!
public static <E> MyStream<E> of(final Collection<E> collection)
{
return new MyStreamImpl<E>(collection);
}
// Yay! Default methods in interfaces!
default boolean containsAny(R item, Comparator<? super R> comparator)
{
return anyMatch(e -> comparator.compare(item, e) == 0);
}
}
public class MyStreamImpl<R>
implements MyStream<R>
{
private final Stream<R> stream;
public MyStreamImpl(final Collection<R> collection)
{
this.stream = Objects.requireNonNull(collection.stream());
}
// delegate all other operations to stream
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用:
MyStream.of(someList).containsAny(item, comparator);
Run Code Online (Sandbox Code Playgroud)
(但实际上代码很多,但意义不大)
归档时间: |
|
查看次数: |
10642 次 |
最近记录: |