ArrayList без повторов - PullRequest
       8

ArrayList без повторов

2 голосов
/ 04 мая 2010

Я использую arraylist в java, и мне нужно добавить целые числа в течение 10 итераций (целое число получается случайным образом из массива целых чисел с именем arrint) без повторений:

for (int i =0; i<10; ++i)
    array.add(integer);

, а затем добавить в тот же массив 20 других целых чисел для того же массива целых чисел (arrint) в течение 20 итераций без повторений

for (int i =0; i<10; ++i)
    array.add(integer);

но допускается повторение между 10 первыми и 20 целыми числами.

спасибо

Ответы [ 5 ]

10 голосов
/ 04 мая 2010

Set, а не List, предотвращает дублирование. Таким образом, вы можете установить Set<Integer> и после его заполнения добавить все его элементы в список (с помощью list.addAll(set)). Затем очистите Set и повторите для следующих 20.

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

6 голосов
/ 04 мая 2010
public class Foo {
  private final Random random = new Random();

  public List<Integer> createList() {
    // Create empty list to store results.
    List<Integer> ret = new ArrayList<Integer>(30);

    // Add 10 randomly generated integers.
    ret.addAll(createRandomIntegers(10));

    // Add another 20 randomly generated integers which could potentially
    // contain integers already added previously (the OP states that this is ok).
    ret.addAll(createRandomIntegers(20));

    return ret;
  }

  /**
   * Utility function that creates a set of randomly generated
   * integers of specified size.  We use a Set to avoid duplicates.
   */
  protected Set<Integer> createRandomIntegers(int sz) {
    Set<Integer> ret = new HashSet<Integer>();

    while (ret.size() < sz) {
      ret.add(random.nextInt());
    }

    return ret;
  }
}
1 голос
/ 04 мая 2010

Я понимаю, что вам нужно иметь список (потому что вам нужно сохранять элементы в том порядке, в котором они были вставлены), а также требуется функциональность набора - предотвращать повторение.

Таким образом, вы можете написать свой собственный класс (скажем, SetList<E>), который будет подкласс ArrayList<E>, а также реализовать интерфейс Set<E>. Для этого вы должны оставить HashSet<E> в качестве атрибута вашего класса SetList<E>. Например: private Set<E> set = new HashSet<E>(); Затем просто синхронизируйте вставки и удаления с набором в атрибуте, и если набор уже содержит вставленный элемент, не вставляйте его. Переопределяющий метод add(E element) будет выглядеть так:

public void add(E element){
    if(set.contains(element)){
        return;
    }
    set.add(element);
    super.add(element);
}

Для других методов это будет аналогично.

Я сам сделал это некоторое время назад, но потом нашел лучшее решение: GlazedLists . Это бесплатная библиотека, которая делает все это и многое другое. Я предлагаю вам использовать UniqueList .

1 голос
/ 04 мая 2010

Я бы лично использовал набор в качестве промежуточного звена для каждой коллекции, которая не допускает повторения, а затем просто добавил бы все это в список. Это далеко не самое «OMG OPTIMIZED» решение, но для будущих читателей очень ясно, что оно делает.

    List<Integer> list = new ArrayList<Integer>();

    Set<Integer> subSet = new HashSet<Integer>();

    for (int i =0; i<10; ++i) {
         subSet.add(integers10[i]);
    }
    list.addAll(subSet);
    subSet.clear();

    for (int i =0; i<20; ++i) {
         subSet.add(integers20[i]);
    }
    list.addAll(subSet);
    subSet.clear();
0 голосов
/ 04 мая 2010

Проект Apache Java Collections обычно содержит код для выполнения большинства общих задач, о которых забыл язык Java. Это один из них:

org.apache.commons.collections.list.SetUniqueList в Commons-Collections .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...