防止arraylist中的重复条目

假设我像这样创建一些对象类

public class thing { private String name; private Integer num; public oDetails (String a, Integer b) { name = a; num = b; } ...gets/ sets/ etc 

现在我想创建一个arraylist来保存一些像这样的对象类。

 ArrayList myList = new ArrayList; thing first = new thing("Star Wars", 3); thing second = new thing("Star Wars", 1); myList.add(first); myList.add(second); 

我想包含某种逻辑,以便在这种情况下…当我们尝试添加对象“second”而不是向arrayList添加新对象时,我们将second.getNum()添加到first.getNum()。 因此,如果您要遍历ArrayList,那就是

 "Star Wars", 4 

我无法想出一个处理这个问题的优雅方法。 随着arraylist的增长,搜索它以确定是否存在重复的名称项变得麻烦。 任何人都可以提供一些指导吗?

您必须创建自己的方法来检查Thing类的name字段是否设置为“星球大战”,然后添加到Class Thing的相应num字段,这是一种可能的解决方案。

另一种解决方案是使用名称字段作为键的Map ,将num字段作为值。

例如:

 public class Thing { private String name; private int num; public Thing(String name, int num) { this.name = name; this.num = num; } } public class ThingMap { Map thingMap; public ThingMap() { this.thingMap = new HashMap<>(); } public void put(Thing t) { String k = t.getName(); Integer v = t.getNum(); if(thingMap.get(k) == null) //no entry exists { thingMap.put(k, v); } else //entry exists { //add to the current value thingMap.put(k, thingMap.get(k) + v); } } public Integer get(String k) { return this.thingMap.get(k); } } public class TestThing { public static void main(String[] args) { ThingMap tMap = new ThingMap(); Thing a = new Thing("Star Wars", 3); Thing b = new Thing("Star Wars", 1); tMap.put(a); tMap.put(b); System.out.println("Current value: " + tMap.get(a.getName()); } } 

希望这可以帮助。

如果要拥有一组唯一对象,请使用Set而不是List

此外,如果您想在对象被认为相等时自己定义,请考虑覆盖该类的equalshashCode方法。

恕我直言,如果你不想改变你的类,使用Map而不是ArrayListMap会更有意义。

您需要以这种方式覆盖类中的equals方法和hashCode方法Thing:

 public class Thing { private String name; private Integer num; public Thing(String a, Integer b) { name = a; num = b; } public void setName(String name) { this.name = name; } public void setNum(Integer num) { this.num = num; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if((obj == null) || (obj.getClass() != this.getClass())){ return false; } Thing that = (Thing)obj; // Use the equality == operator to check if the argument is the reference to this object, // if yes. return true. This saves time when actual comparison is costly. return num == that.num && (name == that.name || (name != null && name.equals(that.name))); } /** * This method returns the hash code value for the object on which this method is invoked. * This method returns the hash code value as an integer and is supported for the benefit of * hashing based collection classes such as Hashtable, HashMap, HashSet etc. This method must * be overridden in every class that overrides the equals method. * * @return */ @Override public int hashCode() { int hash = 7; hash = 31 * hash + num; hash = 31 * hash + (null == name ? 0 : name.hashCode()); return hash; } } 

然后你可以用这种方式使用它:

 ArrayList myList = new ArrayList<>(); Thing first = new Thing("Star Wars", 3); if(!myList.contains(first)){ myList.add(first); } Thing second = new Thing("Star Wars", 1); if(!myList.contains(second)){ myList.add(second); } 

在我的情况下,我使用LinkedHashSet来维护插入的顺序,因为我认为会更有效率。 我没有尝试使用ArrayList这个例子。

有关更多信息,请参阅此处: 为什么我以这种方式覆盖equals和hashCode

如果你想最后使用List而不是写你的Comparator

通过编写Comparator,您可以创建类似set的行为。

 @Override protected Void doInBackground(Void... voids) { HttpHandler sh = new HttpHandler(); String jsonStr = sh.makeServiceCall(Utils.SERVER_URL); Log.e(TAG, "Response from url: " + jsonStr); if (jsonStr != null) { try { JSONObject jsonObject = new JSONObject(jsonStr); JSONArray result = jsonObject.getJSONArray("result"); for (int i = 0; i < result.length(); i++) { JSONObject data = result.getJSONObject(i); String day = data.getString("day"); dataModels.add(day); LinkedHashSet lhs = new LinkedHashSet(); lhs.addAll(dataModels); // Removing ArrayList elements dataModels.clear(); dataModels.addAll(lhs); } } catch (Exception e) { e.printStackTrace(); } } return null; }