假设我有一个对象列表。我想将它们分组到一个列表列表中,其中每个内部列表都包含布尔比较函数返回true的元素
public class VO {
public VO(int age, int val) {
this.age = age;
this.val = val;
}
public int age;
public int val;
}
public void testGrouping() {
// Equal to vo2
VO vo1 = new VO(1, 100);
// Equal to vo1 and vo3
VO vo2 = new VO(3, 105);
// Equal to vo2 but not vo1 (age difference > 2),
// so it belongs into a new bucket
VO vo3 = new VO(5, 110);
// Equal to vo3, so it belongs into the same bucket as vo3
VO vo4 = new VO(7, 116);
List<VO> values = Arrays.asList(vo1, vo2, vo3, vo4);
//Group values using isEqual(VO, VO) into buckets somehow
//Any two values in a bucket must pass the check
//Expected without any specific order:
//[[vo1, vo2, [vo3, vo4]]
}
private boolean isEqual(VO a, VO b) {
return Math.abs(a.age - b.age) <= 2 && Math.abs(a.val - b.val) <= 10;
}这只是我所拥有的数据的一个简化例子,实际上比较方法要复杂得多。重要的是,关于检查,每个对象必须在其存储桶中相互匹配。不能按特定值对对象进行分组/映射。
我已经有了这样的代码,但是需要三层for循环,这花了我大约一天的时间来编写。我很好奇这是否可以通过streams更容易地实现。
发布于 2016-12-09 16:14:59
尝试先映射您的项目,然后使用Collectors.groupingBy()
values.stream().map(name -> name.split("\\s+")).collect(groupingBy(a -> a[1]));这不是返回列表,而是数组-但概念是相同的。
发布于 2021-03-20 07:30:10
您可以稍微修改一下isEqual方法,以便可以将其用作TreeMap的比较器。然后,您可以按如下方式收集TreeMap<VO, List<VO>>。此代码可在Java 7中运行
public static int isEqual(VO a, VO b) {
if (Math.abs(a.age - b.age) > 2 || Math.abs(a.val - b.val) > 10)
return 1;
else if (Math.abs(a.age - b.age) <= 2 && Math.abs(a.val - b.val) <= 10)
return 0;
else
return -1;
}public static void main(String[] args) {
VO vo1 = new VO(1, 100);
VO vo2 = new VO(3, 105);
VO vo3 = new VO(5, 110);
VO vo4 = new VO(7, 116);
List<VO> values = Arrays.asList(vo1, vo2, vo3, vo4);
Map<VO, List<VO>> buckets = new TreeMap<>(new Comparator<VO>() {
@Override
public int compare(VO o1, VO o2) {
return isEqual(o1, o2);
}
});
for (VO vo : values) {
List<VO> list = buckets.get(vo);
if (list == null) {
list = new ArrayList<>();
}
list.add(vo);
buckets.put(vo, list);
}
// output
System.out.println(buckets);
//{VO{1=100}=[VO{1=100}, VO{3=105}], VO{5=110}=[VO{5=110}, VO{7=116}]}
}public static class VO {
public int age, val;
public VO(int age, int val) {
this.age = age;
this.val = val;
}
@Override
public String toString() {
return "VO{" + age + "=" + val + "}";
}
}https://stackoverflow.com/questions/41055131
复制相似问题