如果我有这样的数组列表(伪java代码):
请注意,列表valsSorted将始终按x [0] asc和x [1] desc顺序排序。
List valsSorted = {[1 5][1 4][1 3][2 1][3 2][3 1][4 2][4 1][5 1][6 2][6 1]};
如何使用Java 8流和lambdas过滤此列表,以便获得:
result = {[1 5][2 1][3 2][4 2][5 1][6 2]}
数组的第一项(x [0])是ID,第二项是版本号。因此规则是给出具有最高版本的所有不同ID。
如果我使用for循环,下面的代码就可以了:
ArrayList<int[]> result= new ArrayList();
int keep = -1;
for (int[] x : valsSorted) {
int id = x[0];
int version = x[1];
if(keep == id) continue;
keep = id;
result.add(x);
}
答案 0 :(得分:3)
你使用&#34; distinct&#34;建议使用distinct()
流操作。不幸的是,该操作是硬连线的,以使用流元素的equals()
方法,这对于数组来说并不是很有用。处理此问题的一种方法是将数组包装在一个包装器对象中,该对象具有您正在寻找的相等语义:
class Wrapper {
final int[] array;
Wrapper(int[] array) { this.array = array; }
int[] getArray() { return array; }
@Override
public boolean equals(Object other) {
if (! (other instanceof Wrapper))
return false;
else
return this.array[0] == ((Wrapper)other).array[0];
}
@Override
public int hashCode() { ... }
}
然后在distinct()
之前将你的对象包起来并在之后解开它:
List<int[]> valsDistinct =
valsSorted.stream()
.map(Wrapper::new)
.distinct()
.map(Wrapper::getArray)
.collect(toList());
这会对数据进行一次传递,但每个值会生成一个垃圾对象。这也依赖于按顺序处理的流元素,因为您需要第一个元素。
另一种方法是使用某种有状态的收集器,但这会在任何后续处理开始之前存储整个结果列表,这是你想要避免的。
可能值得考虑使数据元素是实际类而不是双元素数组。通过这种方式,您可以提供合理的相等概念,并且您还可以使值具有可比性,以便您可以轻松地对它们进行排序。
(信用:技术从this answer被盗。)
答案 1 :(得分:1)
class Test{
List<Point> valsSorted = Arrays.asList(new Point(1,5),
new Point(1,4),
new Point(1,3),
new Point(2,1),
new Point(3,2),
new Point(3,1),
new Point(4,2),
new Point(4,1),
new Point(5,1),
new Point(6,2),
new Point(6,1));
public Test(){
List<Point> c = valsSorted.stream()
.collect(Collectors.groupingBy(Point::getX))
.values()
.stream()
.map(j -> j.get(0))
.collect(Collectors.toList());
for(int i=0; i < c.size(); i++){
System.out.println(c.get(i));
}
}
public static void main(String []args){
Test t = new Test()
}
}
我决定使用点类,并将ID字段表示为x,将版本号表示为Y.因此,如果您创建流并按ID对其进行分组,则从那里开始。您可以调用values方法,该方法返回列表集Collection<List<Point>>
。然后,您可以调用此Collection的流,并从每个列表中获取第一个值,该值根据您的规范按降序版本号进行排序,因此它应该是最高版本号。从那里你要做的就是将它们收集到一个列表,数组或任何你认为必要的东西中,然后根据需要进行分配。
这里唯一的问题是它们是无序打印的。这应该是一个简单的解决方案。