如何显示集合是否已添加或删除?

发布于 2024-10-08 12:17:31 字数 2215 浏览 0 评论 0原文

首先,我为发布与“4462626”类似的问题表示歉意。我想比较两个对象(这是父子关系)。下面的代码你觉得怎么样。我认为它效率不高,因为存在太多 for 循环。你能给我建议吗? (注意:我不允许修改 Item.class 并且 ItemEx.class 必须扩展 Item.class)

EXPECTED RESULT
------------------------
add:4
delete:2
------------------------

package com.javastudy;

import java.util.ArrayList;
import java.util.List;

public class CollectionCompareToObjectsForLoop {

 public static void main(String[] args) {

  List<Item> beforeList = new ArrayList<Item>();
  List<ItemEx> afterList = new ArrayList<ItemEx>();

  beforeList.add(new Item(1L));
  beforeList.add(new Item(2L)); // delete
  beforeList.add(new Item(3L));

  afterList.add(new ItemEx(1L));
  afterList.add(new ItemEx(3L));
  afterList.add(new ItemEx(4L)); // added

  // Check Add
  List<Item> addList = new ArrayList<Item>();
  for(Item afterItem : afterList){
   if(checkAdd(afterItem, beforeList)){
    addList.add(afterItem);
   }
  }

  // Check Delete
  List<Item> deleteList = new ArrayList<Item>();
  for(Item beforeItem : beforeList){
   if(checkDelete(beforeItem, afterList)){
    deleteList.add(beforeItem);
   }
  }

  // Print Result
  for(Item item : addList){
   System.out.println("add:" + item.getId());
  }
  for(Item item : deleteList){
   System.out.println("delete:" + item.getId());
  }

 }

 private static boolean checkAdd(Item afterItem, List<Item> beforeList) {
  for(Item beforeItem : beforeList){
   if (afterItem.getId().equals(beforeItem.getId())){
    return false;
   }
  }
  return true;
 }

 private static boolean checkDelete(Item beforeItem, List<ItemEx> afterList) {
  for(Item afterItem : afterList){
   if (beforeItem.getId().equals(afterItem.getId())){
    return false;
   }
  }
  return true;
 }

}

package com.javastudy;

public class Item {

 private Long id;

 public Item(Long id) {
  this.id = id;
 }

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

}

package com.javastudy;

public class ItemEx extends Item {

 private String name;

 public ItemEx(Long id) {
  super(id);
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

Firstly, I apologize for posting similar question to "4462626". I want to compare to two objects (which are parent-child relationship). How do you think following code. I think it is not efficient because too many for-loops exist. Can you advice me? (notice: I am not allowed to modify Item.class and ItemEx.class must extend Item.class)

EXPECTED RESULT
------------------------
add:4
delete:2
------------------------

package com.javastudy;

import java.util.ArrayList;
import java.util.List;

public class CollectionCompareToObjectsForLoop {

 public static void main(String[] args) {

  List<Item> beforeList = new ArrayList<Item>();
  List<ItemEx> afterList = new ArrayList<ItemEx>();

  beforeList.add(new Item(1L));
  beforeList.add(new Item(2L)); // delete
  beforeList.add(new Item(3L));

  afterList.add(new ItemEx(1L));
  afterList.add(new ItemEx(3L));
  afterList.add(new ItemEx(4L)); // added

  // Check Add
  List<Item> addList = new ArrayList<Item>();
  for(Item afterItem : afterList){
   if(checkAdd(afterItem, beforeList)){
    addList.add(afterItem);
   }
  }

  // Check Delete
  List<Item> deleteList = new ArrayList<Item>();
  for(Item beforeItem : beforeList){
   if(checkDelete(beforeItem, afterList)){
    deleteList.add(beforeItem);
   }
  }

  // Print Result
  for(Item item : addList){
   System.out.println("add:" + item.getId());
  }
  for(Item item : deleteList){
   System.out.println("delete:" + item.getId());
  }

 }

 private static boolean checkAdd(Item afterItem, List<Item> beforeList) {
  for(Item beforeItem : beforeList){
   if (afterItem.getId().equals(beforeItem.getId())){
    return false;
   }
  }
  return true;
 }

 private static boolean checkDelete(Item beforeItem, List<ItemEx> afterList) {
  for(Item afterItem : afterList){
   if (beforeItem.getId().equals(afterItem.getId())){
    return false;
   }
  }
  return true;
 }

}

package com.javastudy;

public class Item {

 private Long id;

 public Item(Long id) {
  this.id = id;
 }

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

}

package com.javastudy;

public class ItemEx extends Item {

 private String name;

 public ItemEx(Long id) {
  super(id);
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

太傻旳人生 2024-10-15 12:17:32

我假设您为项目提供的 Id 实际上是 ID,因此具有相同 ID 的项目被视为相等,并且每个 ID 仅有一个项目。然后您可以使用以下代码:

package so4483619;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class AddDel {

  private static <K, V> HashMap<K, V> newLinkedHashMap() {
    return new LinkedHashMap<K, V>();
  }

  private static <K, V> HashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> other) {
    return new LinkedHashMap<K, V>(other);
  }

  private static void computeDeleteAndAdd(List<? extends Item> before, List<? extends Item> after) {
    Map<Long, Item> beforeById = newLinkedHashMap();
    for (Item item : before) {
      beforeById.put(item.getId(), item);
    }

    Map<Long, Item> afterById = newLinkedHashMap();
    for (Item item : after) {
      afterById.put(item.getId(), item);
    }

    Map<Long, Item> onlyBefore = newLinkedHashMap(beforeById);
    onlyBefore.keySet().removeAll(afterById.keySet());

    Map<Long, Item> onlyAfter = newLinkedHashMap(afterById);
    onlyAfter.keySet().removeAll(beforeById.keySet());

    for (Map.Entry<Long, Item> entry : onlyBefore.entrySet()) {
      System.out.println("delete:" + entry.getKey());
    }
    for (Map.Entry<Long, Item> entry : onlyAfter.entrySet()) {
      System.out.println("add:" + entry.getKey());
    }
  }

  public static void main(String[] args) {
    List<Item> beforeList = new ArrayList<Item>();
    List<ItemEx> afterList = new ArrayList<ItemEx>();

    beforeList.add(new Item(1L));
    beforeList.add(new Item(2L)); // delete
    beforeList.add(new Item(3L));

    afterList.add(new ItemEx(1L));
    afterList.add(new ItemEx(3L));
    afterList.add(new ItemEx(4L));

    computeDeleteAndAdd(beforeList, afterList);
  }
}

一些备注:

  • LinkedHashMap 的行为类似于映射,但会记住元素插入的顺序。这是为了使输出可预测,并具有与 beforeListafterList 中相同的顺序。
  • 您的类 ItemItemEx 没有方法 equals(Object)hashCode(),因此它们不能直接用作 HashMap 中的键。我的假设是,您认为具有相同 ID 的两个 Item 是相等的。
  • 这两个辅助方法 newLinkedHashMap 只是在方法 computeDeleteAndAdd 中保存一些按键操作。如果没有这些方法,您将不得不使用 new LinkedHashMap(...) 而不是简单的 newLinkedHashMap(...)

I assume that the Ids you gave to the items are really IDs, so that items having the same ID are considered equal and that there is only one item per ID. Then you can use the following code:

package so4483619;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class AddDel {

  private static <K, V> HashMap<K, V> newLinkedHashMap() {
    return new LinkedHashMap<K, V>();
  }

  private static <K, V> HashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> other) {
    return new LinkedHashMap<K, V>(other);
  }

  private static void computeDeleteAndAdd(List<? extends Item> before, List<? extends Item> after) {
    Map<Long, Item> beforeById = newLinkedHashMap();
    for (Item item : before) {
      beforeById.put(item.getId(), item);
    }

    Map<Long, Item> afterById = newLinkedHashMap();
    for (Item item : after) {
      afterById.put(item.getId(), item);
    }

    Map<Long, Item> onlyBefore = newLinkedHashMap(beforeById);
    onlyBefore.keySet().removeAll(afterById.keySet());

    Map<Long, Item> onlyAfter = newLinkedHashMap(afterById);
    onlyAfter.keySet().removeAll(beforeById.keySet());

    for (Map.Entry<Long, Item> entry : onlyBefore.entrySet()) {
      System.out.println("delete:" + entry.getKey());
    }
    for (Map.Entry<Long, Item> entry : onlyAfter.entrySet()) {
      System.out.println("add:" + entry.getKey());
    }
  }

  public static void main(String[] args) {
    List<Item> beforeList = new ArrayList<Item>();
    List<ItemEx> afterList = new ArrayList<ItemEx>();

    beforeList.add(new Item(1L));
    beforeList.add(new Item(2L)); // delete
    beforeList.add(new Item(3L));

    afterList.add(new ItemEx(1L));
    afterList.add(new ItemEx(3L));
    afterList.add(new ItemEx(4L));

    computeDeleteAndAdd(beforeList, afterList);
  }
}

Some remarks:

  • The LinkedHashMap behaves like a map but remembers the order in which the elements have been inserted. This is to make the output predictable and to have the same order as in the beforeList and afterList.
  • Your classes Item and ItemEx don't have the methods equals(Object) and hashCode(), so they cannot be used directly as keys in a HashMap. This is my assumption that you consider two Items with the same ID to be equal.
  • The two helper methods newLinkedHashMap just save some keystrokes in the method computeDeleteAndAdd. Without these methods you would have to say new LinkedHashMap<Long, Item>(...) instead of a simple newLinkedHashMap(...).
小梨窩很甜 2024-10-15 12:17:32

这个解决方案失去了列表的顺序......

Set<Item> added = new HashSet<Item>(afterList);
Set<Item> removed = new HashSet<Item>(beforeList);
added.removeAll(beforeList);
removed.removeAll(afterList);
for(Item item : added){
   System.out.println("add:" + item.getId());
}
for(Item item : removed){
   System.out.println("delete:" + item.getId());
}

This solution loses the order of the lists...

Set<Item> added = new HashSet<Item>(afterList);
Set<Item> removed = new HashSet<Item>(beforeList);
added.removeAll(beforeList);
removed.removeAll(afterList);
for(Item item : added){
   System.out.println("add:" + item.getId());
}
for(Item item : removed){
   System.out.println("delete:" + item.getId());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文