Java Arraylist - копирование одного на другой без дубликатов - PullRequest
4 голосов
/ 24 августа 2010

У меня есть ArrayList:

Arraylist<Person> list1 = new ArrayList<Person>();
list1.add(new Person("John", 0));
list1.add(new Person("Kane", 0));
list1.add(new Person("Jen", 0));

И еще ArrayList:

Arraylist<Person> list2 = new ArrayList<Person>();
list2.add(new Person("John", 2));
list2.add(new Person("Kane", 4));

Я хочу, чтобы полученный ArrayList содержал:

("John", 2) ("Kane", 4) ("Jen", 0)

Я хочу объединить эти два списка и удалить те, которые имеют значение 0. Если бы я сделал list2.addAll(list1), тогда list2 имеет две записи для «Джона» со значениями 2 и 0. Я хочу удалить запись со значением 0 из этого списка.

Ответы [ 9 ]

8 голосов
/ 24 августа 2010

Гм, в вашей логике программы это выглядит как

new Person("John", 2)

не то, что вы хотите - действительно ли есть «новый человек» по имени Джон? или это тот же самый старый Джон, у которого есть новый счет? Возможно, вам нужна функция для обновления баллов у отдельных людей, например

Person.setValue(int)

Извините, если это на самом деле не отвечает на ваш вопрос, но очень важно убедиться, что у вас есть правильные структуры данных.

2 голосов
/ 24 августа 2010

Похоже, вы хотите максимальное значение для каждого пользователя:

List<Person> all = new ArrayList<Person>();
all.addAll(list1);
all.addAll(list2);

Map<String, Person> map = new HashMap<String, Person>();
for (Person p : all) {
    if (!map.containsKey(p.name) || map.get(p.name).num < p.num) {
        map.put(p.name, p);
    }
}
List<Person> merged = new ArrayList<Person>(map.values());
2 голосов
/ 24 августа 2010

Мне кажется, что вы действительно хотите получить карту. Создайте один из них, и для каждого персонажа в любом списке поместите значение 0 в карту, указав имя этого человека в качестве ключа. Теперь для каждого человека в каждом списке получите значение имени человека на карте, добавьте к нему значение человека и сохраните результат обратно на карту. Теперь, если вам действительно нужно это в ArrayList, просто извлечь пары ключ-значение из карты в новый список.

2 голосов
/ 24 августа 2010

Важен ли порядок? Если нет, то Set имеет больше смысла, чем List. Set исторически недооценивалось программистами, думающими в терминах массивов.

Если порядок не важен, довольно хакерский подход - использовать TreeSet с пользовательским компаратором. В качестве альтернативы используйте Map<String,Person> (возможно, LinkedHashMap).

1 голос
/ 25 августа 2010

Как насчет этого?

Личный класс:

@Override
public boolean equals(Object obj) {
    Person o = (Person) obj;
    if (o.getNombre().equals(this.nombre)) {            
        return true;    
    }
    return false;
}

, то:

    list2.addAll(list1);
    final ArrayList<Person> list3 = list2;
    CollectionUtils.filter(list2, new Predicate() {         

        public boolean evaluate(Object arg0) {
            if (((Person) arg0).getId() == 0 && CollectionUtils.cardinality(arg0, list3) > 1) {
                return false;
            } else {
                return true;
            }
        }
    });
1 голос
/ 24 августа 2010

Из вашего примера видно, что карта от имени к значению независимо от числа является более подходящей структурой данных. С такими картами вы бы просто сделали:

map1.putAll(map2);

Если вы не хотите, чтобы вторая карта выиграла, а вход с более высоким значением, вам нужно будет сделать что-то вроде:

for (Map.Entry<String, Integer> e : map2.entrySet()) {
    Integer v = map1.get(e.getKey());
    if (v == null || v < e.getValue()) {
        map1.put(e.getKey(), e.getValue());
    }
}
1 голос
/ 24 августа 2010

Создайте компаратор, который сравнивает их просто по имени (если у вас еще нет равенства (), которое делает это).

Упорядочить списки в порядке убывания по значению человека (учитывая, что ценность положительная. Это так?)

Затем создайте набор на основе этого компаратора. Теперь вы можете позвонить addAll.

0 голосов
/ 25 августа 2010

Использование карты звучит как ваша лучшая ставка, сет тоже подойдет.b Убедитесь, что Person предоставил правильные выражения equals и hashCode.

0 голосов
/ 24 августа 2010

А как насчет ...

ArrayList<Person> list3 = new ArrayList<Person>();
list3.addAll( list1 );
list3.addAll( list2 );

System.out.println( "BEFORE" );
for ( Person person : list3 )
    System.out.println( person.getName() + " = " + person.getIntParam() );

filterPeople( list3 );

System.out.println( "AFTER" );
for ( Person person : list3 )
    System.out.println( person.getName() + " = " + person.getIntParam() );

Метод фильтра:

public static void filterPeople( List<Person> people ) {
    for ( int i = 0 ; i < people.size(); i++ ) {
        Person person = people.get( i );
        if ( person.getIntParam() == 0 )
            people.remove( i-- );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...