如果先前的过滤器导致空流,则过滤流 JAVA
Filtering a stream if the previous filter resulted in an empty stream JAVA
我花了几个小时试图找到更简单的解决方案,但我一直无法想出最佳答案。
我的问题是我有两个 Set<String>
和一个 List<>
我必须根据集合对列表<>应用第一个过滤器,以防结果为空或只有 1元素,我必须用缺失的 Set<String>
.
再次过滤 List<>
我有这个逻辑,虽然它有效,但在我看来有点难看。
private static final Set<String> ALLOWED_PATH =
Set.of("/anto", "chachi");
private static final Set<String> SECOD_ALLOWED_PATH =
Set.of("/jose", "chuchu");
public void valid(final List<itemObject> itemList) {
List<itemObject> itemFiltered = filterPath(itemList, ALLOWED_PATH);
if (itemFiltered.size() < 2) {
itemFiltered = filterPath(itemList, SECOND_ALLOWED_PATH);
}
//Continue code
}
private List<itemObject> filterPath(
final List<itemObject> itemList, final Set<String> allowedPath) {
return itemList
.stream()
.filter(
item ->
allowedPath
.stream()
.anyMatch(
path ->
item.getPath().contains(path) && item.getValue().equals(Boolean.TRUE)))
.collect(Collectors.toList());
}
在我的示例中,它可以工作,但我不喜欢必须检查列表的大小是否小于 2 才能知道它没有找到第一个的 2 路径的想法,我必须做第二个过滤器。
我不是 lambda 专家,有什么办法让它更优化吗?
谢谢!
考虑根据两者
过滤和收集匹配项
同时设置路径并支付拥有
的成本
另一个(有时是多余的)列表。
添加以下 import
声明:
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
假设未指定的 ItemObject
类型大致为:
interface ItemObject
{
String getPath();
boolean getValue();
}
执行filterPath
如下:
private static List<ItemObject> filterPath(
final List<ItemObject> itemList)
{
class PairCollector<T, U>
{
private final Predicate<T> primaryFilter;
private final Predicate<T> secondaryFilter;
private final Predicate<List<T>> selectFilter;
private final List<T> primaryList;
private final List<T> secondaryList;
PairCollector(Function<Set<U>, Predicate<T>> pairFilter,
Predicate<List<T>> selectFilter,
Set<U> primarySet,
Set<U> secondarySet,
int listCapacity)
{
this.primaryFilter = pairFilter.apply(
primarySet);
this.secondaryFilter = pairFilter.apply(
secondarySet);
this.selectFilter = selectFilter;
this.primaryList = new ArrayList<>(
listCapacity);
this.secondaryList = new ArrayList<>(
listCapacity);
}
PairCollector<T, U> filter(T item)
{
if (primaryFilter.test(item))
primaryList.add(item);
if (selectFilter.test(primaryList)
&& secondaryFilter.test(item))
secondaryList.add(item);
return this;
}
List<T> selectPrimaryElseSecondary()
{
return selectFilter.test(primaryList)
? secondaryList
: primaryList;
}
}
return Collections.unmodifiableList(itemList
.stream()
.reduce(new PairCollector<>((Set<String> paths) ->
(ItemObject item) ->
paths
.stream()
.anyMatch(path -> item
.getPath()
.contains(path)
&& item.getValue()),
list -> list.size() < 2,
ALLOWED_PATH,
SECOND_ALLOWED_PATH,
itemList.size()),
PairCollector::filter,
(left, right) -> {
throw new UnsupportedOperationException();
})
.selectPrimaryElseSecondary());
}
具有仅绑定变量 lambda 的变体实现
表达式。 (Item
在谓词参数
中自由出现
anyMatch
在上面的实现中。)
private static List<ItemObject> filterPath(
final List<ItemObject> itemList)
{
class PairCollector<T, U>
{
private final Predicate<Predicate<U>> primaryFilter;
private final Predicate<Predicate<U>> secondaryFilter;
private final Function<T, Predicate<U>> matcher;
private final Predicate<List<T>> selectFilter;
private final List<T> primaryList;
private final List<T> secondaryList;
PairCollector(Function<Set<U>, Predicate<Predicate<U>>>
pairFilter,
Function<T, Predicate<U>> matcher,
Predicate<List<T>> selectFilter,
Set<U> primarySet,
Set<U> secondarySet,
int listCapacity)
{
this.primaryFilter = pairFilter.apply(
primarySet);
this.secondaryFilter = pairFilter.apply(
secondarySet);
this.matcher = matcher;
this.selectFilter = selectFilter;
this.primaryList = new ArrayList<>(
listCapacity);
this.secondaryList = new ArrayList<>(
listCapacity);
}
PairCollector<T, U> filter(T item)
{
final Predicate<U> matcher_ = matcher.apply(item);
if (primaryFilter.test(matcher_))
primaryList.add(item);
if (selectFilter.test(primaryList)
&& secondaryFilter.test(matcher_))
secondaryList.add(item);
return this;
}
List<T> selectPrimaryElseSecondary()
{
return selectFilter.test(primaryList)
? secondaryList
: primaryList;
}
}
return Collections.unmodifiableList(itemList
.stream()
.reduce(new PairCollector<>(
paths -> paths.stream()::anyMatch,
(ItemObject item) ->
(String path) -> item
.getPath()
.contains(path)
&& item.getValue(),
list -> list.size() < 2,
ALLOWED_PATH,
SECOND_ALLOWED_PATH,
itemList.size()),
PairCollector::filter,
(left, right) -> {
throw new UnsupportedOperationException();
})
.selectPrimaryElseSecondary());
}
我花了几个小时试图找到更简单的解决方案,但我一直无法想出最佳答案。
我的问题是我有两个 Set<String>
和一个 List<>
我必须根据集合对列表<>应用第一个过滤器,以防结果为空或只有 1元素,我必须用缺失的 Set<String>
.
List<>
我有这个逻辑,虽然它有效,但在我看来有点难看。
private static final Set<String> ALLOWED_PATH =
Set.of("/anto", "chachi");
private static final Set<String> SECOD_ALLOWED_PATH =
Set.of("/jose", "chuchu");
public void valid(final List<itemObject> itemList) {
List<itemObject> itemFiltered = filterPath(itemList, ALLOWED_PATH);
if (itemFiltered.size() < 2) {
itemFiltered = filterPath(itemList, SECOND_ALLOWED_PATH);
}
//Continue code
}
private List<itemObject> filterPath(
final List<itemObject> itemList, final Set<String> allowedPath) {
return itemList
.stream()
.filter(
item ->
allowedPath
.stream()
.anyMatch(
path ->
item.getPath().contains(path) && item.getValue().equals(Boolean.TRUE)))
.collect(Collectors.toList());
}
在我的示例中,它可以工作,但我不喜欢必须检查列表的大小是否小于 2 才能知道它没有找到第一个的 2 路径的想法,我必须做第二个过滤器。
我不是 lambda 专家,有什么办法让它更优化吗?
谢谢!
考虑根据两者
过滤和收集匹配项
同时设置路径并支付拥有
的成本
另一个(有时是多余的)列表。
添加以下 import
声明:
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
假设未指定的 ItemObject
类型大致为:
interface ItemObject
{
String getPath();
boolean getValue();
}
执行filterPath
如下:
private static List<ItemObject> filterPath(
final List<ItemObject> itemList)
{
class PairCollector<T, U>
{
private final Predicate<T> primaryFilter;
private final Predicate<T> secondaryFilter;
private final Predicate<List<T>> selectFilter;
private final List<T> primaryList;
private final List<T> secondaryList;
PairCollector(Function<Set<U>, Predicate<T>> pairFilter,
Predicate<List<T>> selectFilter,
Set<U> primarySet,
Set<U> secondarySet,
int listCapacity)
{
this.primaryFilter = pairFilter.apply(
primarySet);
this.secondaryFilter = pairFilter.apply(
secondarySet);
this.selectFilter = selectFilter;
this.primaryList = new ArrayList<>(
listCapacity);
this.secondaryList = new ArrayList<>(
listCapacity);
}
PairCollector<T, U> filter(T item)
{
if (primaryFilter.test(item))
primaryList.add(item);
if (selectFilter.test(primaryList)
&& secondaryFilter.test(item))
secondaryList.add(item);
return this;
}
List<T> selectPrimaryElseSecondary()
{
return selectFilter.test(primaryList)
? secondaryList
: primaryList;
}
}
return Collections.unmodifiableList(itemList
.stream()
.reduce(new PairCollector<>((Set<String> paths) ->
(ItemObject item) ->
paths
.stream()
.anyMatch(path -> item
.getPath()
.contains(path)
&& item.getValue()),
list -> list.size() < 2,
ALLOWED_PATH,
SECOND_ALLOWED_PATH,
itemList.size()),
PairCollector::filter,
(left, right) -> {
throw new UnsupportedOperationException();
})
.selectPrimaryElseSecondary());
}
具有仅绑定变量 lambda 的变体实现
表达式。 (Item
在谓词参数
中自由出现
anyMatch
在上面的实现中。)
private static List<ItemObject> filterPath(
final List<ItemObject> itemList)
{
class PairCollector<T, U>
{
private final Predicate<Predicate<U>> primaryFilter;
private final Predicate<Predicate<U>> secondaryFilter;
private final Function<T, Predicate<U>> matcher;
private final Predicate<List<T>> selectFilter;
private final List<T> primaryList;
private final List<T> secondaryList;
PairCollector(Function<Set<U>, Predicate<Predicate<U>>>
pairFilter,
Function<T, Predicate<U>> matcher,
Predicate<List<T>> selectFilter,
Set<U> primarySet,
Set<U> secondarySet,
int listCapacity)
{
this.primaryFilter = pairFilter.apply(
primarySet);
this.secondaryFilter = pairFilter.apply(
secondarySet);
this.matcher = matcher;
this.selectFilter = selectFilter;
this.primaryList = new ArrayList<>(
listCapacity);
this.secondaryList = new ArrayList<>(
listCapacity);
}
PairCollector<T, U> filter(T item)
{
final Predicate<U> matcher_ = matcher.apply(item);
if (primaryFilter.test(matcher_))
primaryList.add(item);
if (selectFilter.test(primaryList)
&& secondaryFilter.test(matcher_))
secondaryList.add(item);
return this;
}
List<T> selectPrimaryElseSecondary()
{
return selectFilter.test(primaryList)
? secondaryList
: primaryList;
}
}
return Collections.unmodifiableList(itemList
.stream()
.reduce(new PairCollector<>(
paths -> paths.stream()::anyMatch,
(ItemObject item) ->
(String path) -> item
.getPath()
.contains(path)
&& item.getValue(),
list -> list.size() < 2,
ALLOWED_PATH,
SECOND_ALLOWED_PATH,
itemList.size()),
PairCollector::filter,
(left, right) -> {
throw new UnsupportedOperationException();
})
.selectPrimaryElseSecondary());
}