繁体   English   中英

检查两个对象列表是否具有相同的属性值

[英]check if two lists of objects have the same value of an attribute

我有两个对象列表localListremotList ,两个列表都有一个同意属性

如果两个列表相同,我想检查同意属性的值

如果不是,我想从 localList 中删除所有对象不具有 remotList 中存在的相同同意值,并添加所有对象具有 remotList 而不是 localList 中存在的相同同意值

我实施了这个解决方案,但我想改进它

Java 示例

    class Customer{

    private Long id;
    private String name;
    private Integer consent;

    public Customer(Long id, String name, Integer consent) {
        this.id = id;
        this.name = name;
        this.consent = consent;
    }

    public Integer getConsent() {
        return consent;
    }

    @java.lang.Override
    public java.lang.String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", consent=" + consent +
                '}';
    }
}

 public static void main(String[] args) {

    List<Customer> localList = new ArrayList<>();
    localList.add(new Customer(1L, "name1", 12));
    localList.add(new Customer(2L, "name2", 13));
    localList.add(new Customer(3L, "name3", 14));
    localList.add(new Customer(4L, "name4", 15));

    List<Customer> remoteList = new ArrayList<>();
    remoteList.add(new Customer(10L, "name1", 12));
    remoteList.add(new Customer(11L, "name2", 11));
    remoteList.add(new Customer(12L, "name3", 14));
    remoteList.add(new Customer(13L, "name4", 16));

    Map<Integer, Customer> map = remoteList.stream()
            .collect(Collectors.toMap(s -> s.getConsent() , s -> s));
    Map<Integer, Customer> map2 = localList.stream()
            .collect(Collectors.toMap(s -> s.getConsent() , s -> s));

      List<Customer> remove = new ArrayList<>();

    localList.forEach(e -> {
        if(map.get(e.getConsent()) == null ) {
            remoteList.add(e);
        }
    });

    remoteList.forEach(e -> {
        if(map2.get(e.getConsent()) == null ) {
            remove.add(e);
        }
    });

    remove.forEach(e ->  remoteList.remove(e));

    remoteList.forEach(System.out::println);

远程列表

Customer{id=10, name='name1', consent=12}
Customer{id=11, name='name2', consent=11}
Customer{id=12, name='name3', consent=14}
Customer{id=13, name='name4', consent=16}

本地列表

Customer{id=1, name='name1', consent=12}
Customer{id=2, name='name2', consent=13}
Customer{id=3, name='name3', consent=14}
Customer{id=4, name='name4', consent=15}

结果

Customer{id=10, name='name1', consent=12}
Customer{id=12, name='name3', consent=14}
Customer{id=2, name='name2', consent=13}
Customer{id=4, name='name4', consent=15}

对于第一部分,您可以为remoteList创建一个 map,按name映射每个客户。 我们这样做是为了能够更快地搜索远程客户。

Map<String, Customer> customerByName = remoteList.stream()
                .collect(Collectors.toMap(Customer::getName, customer -> customer));

localList.removeIf(customer -> !Objects.equals(customer.getConsent(),
                customerByName.get(customer.getName()).getConsent()));

请注意, Customer class 需要一个 getter 作为name

对于第二部分,我们还可以像之前所做的那样为localList创建一个 map。 我们遍历remoteList并过滤localList中不存在的每个元素(至少我相信这是您想要完成的)。

Map<String, Customer> localCustomerByName = localList.stream()
                .collect(Collectors.toMap(Customer::getName, customer -> customer));

localList.addAll(remoteList.stream()
                .filter(customer -> !localCustomerByName.containsKey(customer.getName()))
                .collect(Collectors.toList()));
Map<Integer, Customer> map = remoteList.stream()
            .collect(Collectors.toMap(s -> s.getConsent() , s -> s));
List<Customer> hasDiffLastItem = localList.stream()
                .filter(s -> !map.get(getConsent).getConsent().equals(s.getConsent()))
                .collect(Collectors.toList());

这是一种方法。 我使用了链表,因为它们在删除项目方面更有效。

  • 首先,为一组创建一个比较器。 树集将采用比较器代替 equals 实现。
  • 然后遍历远程列表,如果项目出现在本地集合中,则删除它们。
  • 然后遍历本地列表,如果项目没有出现在远程集中,则删除它们。
Set<Customer> remoteSet = new TreeSet<>(comp);
Set<Customer> localSet = new TreeSet<>(comp);
remoteSet.addAll(remoteList);
localSet.addAll(localList);

Iterator<Customer> iter = localList.iterator();
while(iter.hasNext()) {
    Customer s = iter.next();
    if (remoteSet.contains(s)) {
        iter.remove();
    }
}
iter = remoteList.iterator();
while(iter.hasNext()) {
    Customer s = iter.next();
    if (!localSet.contains(s)) {
        iter.remove();
    }
}

您可以根据需要组合列表,但这里是背靠背的结果。

localList.forEach(System.out::println);
remoteList.forEach(System.out::println);

印刷

Customer{id=2, name='name2', consent=13}
Customer{id=4, name='name4', consent=15}
Customer{id=10, name='name1', consent=12}
Customer{id=12, name='name3', consent=14}

我使用您和我的方法尝试了不同的值,output 是相同的。 我建议您自己检查一下,因为我不完全确定您希望它如何工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM