Prevent duplicate entries in arraylist

好久不见. 提交于 2019-11-27 02:25:17

问题


Say I create some object class like so

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

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

Now I want to create an arraylist to hold a number of this object class like so.

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);

I would like to include some sort of logic so that in this case...when we try and add object "second" rather than add a new object to the arrayList, we add second.getNum() to first.getNum(). So if you were to iterate through the ArrayList it would be

"Star Wars", 4

I am having trouble coming up with an elegant way of handling this. And as the arraylist grows, searching through it to determine if there are duplicate name items becomes cumbersome. Can anyone provide some guidance on this?


回答1:


You would have to create your own method to check to see if the the name field of class Thing was set to "Star Wars" then add to the corresponding num field of Class Thing, that is one possible solution.

Another solution is to use a Map with the name field as the key, and the num field as the value.

ex:

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());
   }

}

Hope this helps.




回答2:


If you want to have a set of unique objects, use Set instead of List.

Also, if you want to define by yourself when objects are considered equal, consider overriding the equals and hashCode methods of the class.




回答3:


IMHO, it makes more sense to use a Map<String, Integer> instead of the ArrayList, or a Map<String, Thing> if you don't want to change your class.




回答4:


You need to override the equals method and hashCode method in your class Thing in this way:

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;
        }
    }

Then you could use it in this way:

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);
}

In my case I'm using LinkedHashSet to maintain the order of insertion and because I think is going to be more efficient. I didn't try this example with ArrayList.

For more information you can read from here: why I override equals and hashCode in this way




回答5:


If you want to use List finally than Write your Comparator,

by writing Comparator you can create behaviour like set.




回答6:


@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;
        }


来源:https://stackoverflow.com/questions/9962082/prevent-duplicate-entries-in-arraylist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!