class Human {
Long humanId;
String name;
Long age;
}
class SuperHuman {
Long superHumanId;
Long humanId;
String name;
Long age;
}我有两份名单。人类列表和superHumans列表。我想从这两个列表中创建一个列表,以确保如果一个人是超人,那么使用java 8在列表中只出现一次。有一个很好的方法吗?更新:这些是不同的类,也就是说,它们都没有扩展其他类。我希望最后的名单是超人。如果一个人已经是超人了,我们就会忽略那个人类的物体。如果一个人不是超人,我们就把人类对象转化为超人类对象。理想的情况下,我会想要按他们的年龄排序,在最后,这样我就可以得到一个按日期排序的超人名单,按降序排序。
发布于 2017-07-21 06:51:12
根据你最新的问题:
List<Human> humans = ... // init
List<SuperHuman> superHumans = ... // init
Set<Long> superHumanIds = superHumans.stream()
.map(SuperHuman::getHumanId)
.collect(toSet());
humans.stream()
.filter(human -> superHumanIds.contains(human.getHumanId()))
.map(this::convert)
.forEach(superHumans::add);
superHumans.sort(Comparator.comparing(SuperHuman::getAge));假设这个类有另一个具有以下签名的方法:
private Superhuman convert(Human human) {
// mapping logic
}发布于 2017-07-21 07:28:40
对于如何重新分解代码以使其更好,您确实有其他的建议,但是如果您不能这样做,有一种方法--通过一个没有那么复杂的自定义Collector。
自定义收集器还可以让您实际决定要保留哪个条目--已经收集的条目、即将到来的条目或最新的“遭遇顺序”项目获胜。这将需要一些代码更改-但它是可行的,以防您需要它。
private static <T> Collector<Human, ?, List<Human>> noDupCollector(List<SuperHuman> superHumans) {
class Acc {
ArrayList<Long> superIds = superHumans.stream()
.map(SuperHuman::getHumanId)
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<Long> seen = new ArrayList<>();
ArrayList<Human> noDup = new ArrayList<>();
void add(Human elem) {
if (superIds.contains(elem.getHumanId())) {
if (!seen.contains(elem.getHumanId())) {
noDup.add(elem);
seen.add(elem.getHumanId());
}
} else {
noDup.add(elem);
}
}
Acc merge(Acc right) {
noDup.addAll(right.noDup);
return this;
}
public List<Human> finisher() {
return noDup;
}
}
return Collector.of(Acc::new, Acc::add, Acc::merge, Acc::finisher);
}假设您有以下条目:
List<SuperHuman> superHumans = Arrays.asList(
new SuperHuman(1L, 1L, "Superman"));
//
List<Human> humans = Arrays.asList(
new Human(1L, "Bob"),
new Human(1L, "Tylor"),
new Human(2L, "John"));这样做:
List<Human> noDup = humans.stream()
.collect(noDupCollector(superHumans));
System.out.println(noDup); // [Bob, Tylor]发布于 2017-07-21 06:44:50
尝尝这个。
List<Object> result = Stream.concat(
humans.stream()
.filter(h -> !superHumans.stream()
.anyMatch(s -> h.humanId == s.humanId)),
superHumans.stream())
.collect(Collectors.toList());https://stackoverflow.com/questions/45230629
复制相似问题