假设我们有一个三维的物体列表。
class OneDObject {
int id;
List<Integer> list;
OneDObject(int id, List<Integer>list) { // Constructor }
// Getters and Setters
}
class TwoDObject {
int id;
List<OneDObject> list;
TwoDObject(int id, List<OneDObject> list) { // Constructor }
// Getters and Setters
}
var l1 = List.of(1,2,4);
var l2 = List.of(2,4,6);
var obj1d1 = new OneDObject(1, l1);
var obj1d2 = new OneDObject(2, l2);
var l3 = List.of(obj1d1, obj1d2);
var l4 = List.of(obj1d1);
var obj2d1 = new TwoDObject(3, l3);
var obj2d2 = new TwoDObject(4, l4);
var l5 = List.of(obj2d1, obj2d2); // 3-d list
假设我想过滤“l5”,这样如果最里面的列表中的任何元素是奇数,那么整个列表都应该被删除,如果这使得第二级列表为空,那么作为回报应该被删除。
因此,对于给定的示例,在过滤之前,如果:
[[[1,2,4],[2,4,6]], [[1,2,4]]]
过滤后,它应该是:
[[[2,4,6]]]
如何使用Java中的流来实现这一点?
为了实现您想要的,我们需要混合使用功能接口的流操作和收集方法。
在下面的代码中,我们首先使用peek聚合操作来检查每个TwoDbObj实例。
然后,对于它们中的每一个,我们检查它们的OneDbObj列表,并删除至少包含奇数的实例。
一旦OneDbObj列表被最里面的整数列表过滤,我们只保留其列表至少包含一个值的TwoDbObj实例(它也可以被写为!isEmpty)。
public class Main {
public static void main(String[] args) {
List<TwoDObject> l5 = new ArrayList<>(List.of(
new TwoDObject(3, new ArrayList<>(List.of(
new OneDObject(1, new ArrayList<>(List.of(1, 2, 4))),
new OneDObject(2, new ArrayList<>(List.of(2, 4, 6)))))),
new TwoDObject(4, new ArrayList<>(List.of(new OneDObject(1, new ArrayList<>(List.of(1, 2, 4))))))));
System.out.println(l5);
List<TwoDObject> listFiltered = l5.stream()
.peek(twoObj -> twoObj.getList().removeIf(oneObj -> oneObj.getList().stream().anyMatch(i -> i % 2 != 0))) //For each TwoDbObj we get rid of the OneDbObj list whose elements contain at least an odd number
.filter(twoObj -> twoObj.getList().size() > 0) //Keeping only the TwoDbObj instances whose list contains any element
.collect(Collectors.toList());
System.out.println(listFiltered);
}
}
在这里,我将粘贴示例类的部分实现,以便模拟我执行的测试。
class OneDObject {
int id;
List<Integer> list;
OneDObject(int id, List<Integer> list) {
this.id = id;
this.list = list;
}
public List<Integer> getList() {
return list;
}
public String toString() {
return String.format("%s", list);
}
}
class TwoDObject {
int id;
List<OneDObject> list;
TwoDObject(int id, List<OneDObject> list) {
this.id = id;
this.list = list;
}
public List<OneDObject> getList() {
return list;
}
public String toString() {
return String.format("%s", list);
}
}
这是最后一段代码(用Java编写,但我认为它几乎可以与Kotlin互换)
List<TwoDObject> l6 = l5.stream()
.peek(twoDObject -> {
List<OneDObject> filteredOneDObjectList = twoDObject.getList()
.stream()
.filter(oneDObject -> oneDObject.getList()
.stream()
.noneMatch(i -> i % 2 == 1))
.toList();
twoDObject.setList(filteredOneDObjectList);
})
.filter(twoDObject -> twoDObject.getList().size() > 0)
.toList();
首先,我们通过调用Stream#peek
遍历每个twoDObject
,然后对其列表进行流式处理,过滤掉每个包含奇数的oneDObject。然后列表被保存回当前的twoDObject。
最后我们过滤掉所有空的两个对象。
请注意,Stream#peek
通常只能用于调试,而不能更改流元素。
在这种情况下,它也可以用
List<TwoDObject> l6 = l5.stream()
.map(twoDObject -> {
...
return twoDObject;
})
...
由于您需要更新列表,在下面的解决方案中,我使用List
的removeIf
方法删除任何不符合必要条件的元素。因此,要想让removeIf
发挥作用,列表不应该是不变的。因此,替换var list=list。关于(…)
带有
var list=new ArrayList的代码
现在,这个问题可以分为以下几个部分:
谓词来标识列表中是否有任何奇数元素
Predicate<OneDObject> hasOdd = obj-> obj.getList().stream().anyMatch(i -> i % 2 != 0);
Predicate<TwoDObject> validate2d = obj -> {
// remove any 1d list that has atleast one odd number.
obj.getList().removeIf(hasOdd);
// check if there are any valid 1d lists
return obj.getList().isEmpty();
};
l5.removeIf(validate2d); // l5 will now contain only the 2d object having [2,4,6] list
作为这个答案的后续(关于方法1),我想更进一步: 我想根据某些标准筛选子对象。我尝试了下面的查询,但它仍然没有筛选出孙实体下的对象。 关联类实体 类关系ParentEntity<1-OneTomany-x>ChildEntity<1-OneTomany-x>GrandChildEntity
我正在尝试根据另一个列表中存在的值筛选一个列表。我已经经历了其他类似的问题,并试图利用这些来实现我的目标,但无法做到这一点。 列表1由类(L1)的对象组成 列表2由类(L2)的对象组成 因此,筛选后,列表1将不包含,因为该模型与中的不匹配。 我怎么能这么做?
我需要从给定的超级列表中提取子列表,如下所述。 假设我有一个“Person”对象的超级列表如下: 让Person类定义如下: 通过使用Java Streams API,我如何获取包含如下条目的子列表(注意,必须获取具有相同名称的对象的重复实例): 有人能帮我用Java 8流API实现这一点吗? 附注:我不会预先知道这些对象的名称是什么值。
我正试图找出如何解决这两个问题,我有我的ES 5.6索引。 我需要创建两个单独的脚本过滤器: 1-筛选employee数组大小==3的文档 2-筛选数组第一个元素为“name”==“John”的文档 我试图做一些第一步,但我无法迭代列表。我总是有一个空指针异常错误。
我使用的是spring,我用定义了bean。它是一个包含对象的列表。 这是我的数据privider类: 在configuration类中,我从创建了-它可以工作。 在服务中,我想从列表中修改一个对象,该对象与令牌字符串匹配,并且已将设置为。 这条小溪运行良好。现在,当有人为已确认的对象调用方法两次时,我希望抛出。我怎么能用这条小溪做到这一点呢?我可以将放在哪里? 编辑: 我现在的解决方案。我使用而
我是Elasticsearch的新手,我试图创建一个过滤器来检索具有特定属性的文档。 属性在映射中定义为嵌套对象,如下所示: 我试图以以下形式执行一个复杂的查询: 这是elasticsearch 2.x。我做错了什么?