有没有办法使用java 8功能和lambdas执行以下操作?
我有这个班级
public class A{
private String id;
private int version;
// getters...
}
输入(列表按ID和升序排序):
[{"1",1},{"1",2},{"2",1},{"2",2}]
我希望列表中包含每个id的最高版本,因此结果应如下所示:
[{"1",2},{"2",2}]
我已经有了解决方案,但我不喜欢它。我想也许有一个更好的方法用java 8。
static List<A> removeOldVersions(List<A> aList) {
Map<String, A> map = new HashMap<>();
aList.forEach(a -> map.put(a.getId(), a));
return (List<A>) map.values();
}
答案 0 :(得分:3)
好吧,你可以收集到Map
并通过BinaryOperator.maxBy
合并条目。计算完成后,在其上调用values
(将返回Collection<A>
):
yourList.stream()
.collect(Collectors.toMap(
A::getId,
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(A::getVersion))))
.values()
答案 1 :(得分:1)
这有两种方法,它们都使用Comparators
,我建议您在以下链接中阅读更多相关内容:
https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
我想向您展示我最简单的方法,而无需编写自己的过滤器/独特的alghorytm。此解决方案将使用Java 8的Stream API。
(假设您在两个示例中都使用了ArrayList
或HashSet
。)
public class Sorter {
private final class A {
private String id;
private int version;
private A(String id, int version) {
this.id = id;
this.version = version;
}
public String getId() {
return id;
}
public int getVersion() {
return version;
}
}
public void sort() {
final ArrayList<A> list = new ArrayList<A>() {{
add(new A("1", 1));
add(new A("1", 2));
add(new A("2", 1));
add(new A("2", 2));
}};
//Using HashSet so we cannot have any duplicates.
list.stream().sorted(Comparator.comparingInt(o -> o.version)).filter(distinctByKey(a -> a.id)).collect(Collectors.toSet());
}
private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor)
{
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
希望这已经回答了你的问题。
答案 2 :(得分:0)
将每一对添加到Map
,检查它是否已存在并且在覆盖之前具有较低的值。
经典方法:
{
List<A> in = Arrays.asList(new A("'1'", 1),
new A("'1'", 2),
new A("'2'", 1),
new A("'2'", 2));
Map<String, Integer> map = new LinkedHashMap<>(in.size()); // 'Linked' just keeps the original ordering
for (A element : in) {
@Nullable Integer version = map.get(element.id);
if (version == null || version < element.version)
map.put(element.id, element.version);
}
System.out.println(map);
}
输出:
{'1'=2, '2'=2}