Предотвратить повторяющиеся записи в arraylist - PullRequest
7 голосов
/ 01 апреля 2012

Скажем, я создаю некоторый класс объектов, например,

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

У меня проблемы с придумыванием элегантного способа справиться с этим. И по мере роста массива, поиск в нем, чтобы определить, есть ли дублирующие элементы имени, становится громоздким. Кто-нибудь может дать некоторые рекомендации по этому вопросу?

Ответы [ 6 ]

4 голосов
/ 01 апреля 2012

Вы должны создать свой собственный метод, чтобы проверить, установлено ли для поля name класса Thing значение «Звездные войны», а затем добавить к соответствующему полю num класса Thing, что является одним из возможных решений. ,

Другое решение - использовать 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());
   }

}

Надеюсь, это поможет.

4 голосов
/ 01 апреля 2012

Если вы хотите иметь набор уникальных объектов, используйте Set вместо List.

Кроме того, если вы хотите сами определить, когда объекты считаются равными, рассмотрите возможность переопределения методов класса equals и hashCode.

1 голос
/ 20 октября 2015

Вам нужно переопределить метод равно и метод 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.

Дополнительную информацию вы можете прочитать здесь: почему я переопределяю equals и hashCode таким образом

1 голос
/ 01 апреля 2012

ИМХО, имеет смысл использовать Map<String, Integer> вместо ArrayList или Map<String, Thing>, если вы не хотите менять свой класс.

0 голосов
/ 31 августа 2018
@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;
        }
0 голосов
/ 01 апреля 2012

Если вы хотите использовать список наконец, чем написать свой Comparator,

, написав Comparator, вы можете создать поведение как set.

...