首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java 8从两个具有唯一id的列表中合并对象

使用Java 8从两个具有唯一id的列表中合并对象
EN

Stack Overflow用户
提问于 2017-07-21 06:35:47
回答 4查看 14.2K关注 0票数 3
代码语言:javascript
复制
class Human {
    Long humanId;
    String name;
    Long age;
}


class SuperHuman {
    Long superHumanId;
    Long humanId;
    String name;
    Long age;
}

我有两份名单。人类列表和superHumans列表。我想从这两个列表中创建一个列表,以确保如果一个人是超人,那么使用java 8在列表中只出现一次。有一个很好的方法吗?更新:这些是不同的类,也就是说,它们都没有扩展其他类。我希望最后的名单是超人。如果一个人已经是超人了,我们就会忽略那个人类的物体。如果一个人不是超人,我们就把人类对象转化为超人类对象。理想的情况下,我会想要按他们的年龄排序,在最后,这样我就可以得到一个按日期排序的超人名单,按降序排序。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-07-21 06:51:12

根据你最新的问题:

代码语言:javascript
复制
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));

假设这个类有另一个具有以下签名的方法:

代码语言:javascript
复制
private Superhuman convert(Human human) {
    // mapping logic
}
票数 9
EN

Stack Overflow用户

发布于 2017-07-21 07:28:40

对于如何重新分解代码以使其更好,您确实有其他的建议,但是如果您不能这样做,有一种方法--通过一个没有那么复杂的自定义Collector

自定义收集器还可以让您实际决定要保留哪个条目--已经收集的条目、即将到来的条目或最新的“遭遇顺序”项目获胜。这将需要一些代码更改-但它是可行的,以防您需要它。

代码语言:javascript
复制
 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);
}

假设您有以下条目:

代码语言:javascript
复制
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"));

这样做:

代码语言:javascript
复制
List<Human> noDup = humans.stream()
            .collect(noDupCollector(superHumans));

System.out.println(noDup); // [Bob, Tylor]
票数 2
EN

Stack Overflow用户

发布于 2017-07-21 06:44:50

尝尝这个。

代码语言:javascript
复制
List<Object> result = Stream.concat(
    humans.stream()
        .filter(h -> !superHumans.stream()
            .anyMatch(s -> h.humanId == s.humanId)),
    superHumans.stream())
    .collect(Collectors.toList());
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45230629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档