Как избежать Java.util.IllegalStateException в следующем коде? - PullRequest
2 голосов
/ 05 октября 2011

У меня есть список целых чисел с повторяющимися значениями в нем.Что мне нужно сделать, это найти дубликаты целых чисел, добавить их значение, а затем добавить результат в список, удалив найденные дубликаты.Вот что я делаю:

List<Integer> list1 = new ArrayList<Integer>();
    list1.add(2);
    list1.add(5);
    list1.add(3);
    list1.add(5);
    list1.add(4);

    List<Integer> list2 = new ArrayList<Integer>();
    Iterator<Integer> it = list1.iterator();
    while (it.hasNext()) {
        Integer int1 = it.next();
        if (list2.isEmpty()) {
            list2.add(int1);
            it.remove();
        } else {
            ListIterator<Integer> it2 = list2.listIterator();
            while (it2.hasNext()) {
                Integer int2 = it2.next(); 
                if (int2 != int1) {
                    it2.add(int1);
                    it.remove();// I get exception here

                } else {                        
                    it2.remove();
                    it.remove();
                    Integer newint = int1 + int2;
                    it2.add(newint);
                }                   
            }
        }
    }       
    for(Integer in : list2){
        System.out.println(in);
    }

Вывод должен выглядеть как
2<br> 10<br> 3<br> 4

Спасибо за ваше время.

Ответы [ 5 ]

3 голосов
/ 05 октября 2011

Как говорили другие авторы, вы не можете удалить их во время итерации.Несмотря на то, что есть «хитрости», возиться с коллекцией во время итерации - верный способ получить странные ошибки времени выполнения.

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

private List<Integer> sumAndUniqDuplicates(List<Integer> list) {
    LinkedHashMap<Integer, Integer> lookup = new LinkedHashMap<Integer, Integer>();
    for (Integer value : list) {
        Integer prevValue = lookup.get(value);
        prevValue = (prevValue == null) ? 0 : prevValue;
        lookup.put(value, prevValue + value);
    }
    return new ArrayList<Integer>(lookup.values());
}
2 голосов
/ 05 октября 2011

Если вам разрешено использовать карту, вы можете сделать что-то простое (входящий псевдокод):

create empty Map m
for each Integer x in list1 do
    if m does not contain key x 
        m.put(x, x)
    else
        m.put(x, m.get(x) + x)
    endif
done

Ваш результат - значения m (который является коллекцией).

Редактировать: Вы сказали, что у вас есть LatLng вместо целых чисел - я не знаю LatLng, но после быстрого Google я бы сделал снимок следующего, предполагая, что вы хотите "добавить" ваши латинские баллы:

create empty Map<LatLng, LatLng> m
for each LatLng x in list1 do
    if not m.containsKey(x) 
        m.put(x, x)
    else
        m.put(x, LatLng.newInstance(m.get(x).getLatitude() + x.getLatitude(),
                                    m.get(x).getLongitude() + x.getLongitude()))
    endif
done

Единственная проблема, которую я вижу здесь, состоит в том, что это m.containsKey(x) зависит от правильной реализации equals, что я не уверен после прочтения этого

2 голосов
/ 05 октября 2011

Это потому, что вы удаляете один и тот же элемент дважды.Первый раз в if(list2.isEmpty()) (потому что list2 пуст в начале и сразу после этого в теле else.

1 голос
/ 05 октября 2011

Вы не можете удалить текущий элемент дважды.Вам нужно переосмыслить свою логику.

1 голос
/ 05 октября 2011

Из документации для метода remove:

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

...