防止arraylist中的重复条目

时间:2012-04-01 05:16:39

标签: java arraylist no-duplicates

假设我创建了一个像这样的对象类

public class thing {
        private String name; 
        private Integer num;

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

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

ArrayList<thing> myList = new ArrayList<thing>;
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的增长,搜索它以确定是否存在重复的名称项变得麻烦。任何人都可以提供一些指导吗?

6 个答案:

答案 0 :(得分:4)

如果您想拥有一组唯一对象,请使用Set代替List

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

答案 1 :(得分:4)

您必须创建自己的方法来检查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<String, Integer> 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());
   }

}

希望这有帮助。

答案 2 :(得分:1)

恕我直言,如果你不想改变你的班级,使用Map<String, Integer>而不是ArrayListMap<String, Thing>会更有意义。

答案 3 :(得分:1)

你需要在你的类中覆盖 equals 方法和 hashCode 方法这样:

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<Thing> 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这个例子。

有关详细信息,请参阅此处:why I override equals and hashCode in this way

答案 4 :(得分:0)

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

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

答案 5 :(得分:-1)

@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<String> lhs = new LinkedHashSet<String>();
                        lhs.addAll(dataModels);
                        // Removing ArrayList elements
                        dataModels.clear();
                        dataModels.addAll(lhs);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }