2013-10-02 5 views
2

Я пытаюсь написать программу на Java, которая будет вычислять все комбинации элементов в массиве с целым числом (с 5 элементами) и выводить эти комбинации в ArrayList. Я включил свой код ниже.Java: проблема с добавлением элементов в ArrayList <ArrayList <Integer>>

Я использую побитовые операции для нахождения комбинаций. Каждая комбинация построена как ArrayList (Integer), называемая «writeitem». Затем я хочу сохранить их в другом ArrayList, называемом «master», который должен иметь форму ArrayList (ArrayList (Integer)). [по причинам форматирования <> должны быть заменены на(); они не отображаются иначе ...]

Проблема возникает при попытке сохранить каждую комбинацию в «Master» ArrayList. Если вы запустите код ниже, функция printf покажет, что комбинация построена правильно. Однако, как только я попрошу его «добавить» в «master», он, похоже, не добавляется к концу «master». Скорее всего, «хозяин» перезаписывается i копиями только что построенной комбинации.

Так, например, если я вызываю функцию на [1,2,3,4,5], мой «основной» массив заканчивается 31 копией [1,2,3,4,5] (31-ю комбинацию можно найти).

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

static ArrayList<ArrayList<Integer>> master = new ArrayList<ArrayList<Integer>>(); 
public static void generatecombs(int[] x){ 

    ArrayList<Integer> writeitem = new ArrayList<Integer>(); //empty list to construct each comb 

    for(int i=1;i<32;i++){ 

     writeitem.clear(); //clear before constructing next combination 

     if((i & 1)>0){   //check if each element is present in combination 
      writeitem.add(x[0]); 
     } 
     if((i & 2)>0){ 
      writeitem.add(x[1]); 
     } 
     if((i & 4)>0){ 
      writeitem.add(x[2]); 
     } 
     if((i & 8)>0){ 
      writeitem.add(x[3]); 
     } 
     if((i & 16)>0){ 
      writeitem.add(x[4]); 
     } 

     System.out.printf("The %dth combination is %s\n", i,writeitem); 
     master.add(writeitem); //output constructed element 
     System.out.printf("The collection so far is: %s\n", master); 
    } 
} 

ответ

1

Переместить новый внутри цикла

static ArrayList<ArrayList<Integer>> master = new ArrayList<ArrayList<Integer>>(); 

public static void generatecombs(int[] x){ 

    for(int i=1;i<32;i++){ 

     ArrayList<Integer> writeitem = new ArrayList<Integer>(); // new list to construct each comb 
     if((i & 1)>0){   //check if each element is present in combination 
      writeitem.add(x[0]); 
     } 
     if((i & 2)>0){ 
      writeitem.add(x[1]); 
     } 
     if((i & 4)>0){ 
      writeitem.add(x[2]); 
     } 
     if((i & 8)>0){ 
      writeitem.add(x[3]); 
     } 
     if((i & 16)>0){ 
      writeitem.add(x[4]); 
     } 

     System.out.printf("The %dth combination is %s\n", i,writeitem); 
     master.add(writeitem); //output constructed element 
     System.out.printf("The collection so far is: %s\n", master); 
    } 
} 
+0

Спасибо! И благодаря каждому за их ответы он работает сейчас, и я вижу, что я сделал не так. – lexipenia

0

удалить, что ясно() method.from для loop.after каждой итерации ясно() удаляет значения из ArrayList поставить вас ArrayList создание внутри для.

+0

нет, понятно, необходимо. Замените ясность новым внутри цикла. – Aubin

0

Переместить конструкцию writeitem внутри для цикла. Вы не хотите повторно использовать один и тот же массив.

0

Еще одно решение - клонировать при добавлении в родительский список перед очисткой writeItem.

master.add(writeitem.clone()); 
+0

NO, clone Возвращает неглубокую копию этого LinkedList. – Aubin

0

Причина вы получаете 31 копий, потому что вы работаете через цикл, вытирая writeitem массив чистить каждый раз, добавляя к нему, и печать его в то же время в течение цикла, который затем повторяется еще 30 раз, пока я не достигнет 32.

Удалить writeitem.clear(); и посмотреть, как вы с этой

+0

Нет, следующий цикл продолжает добавлять в ранее выделенный список ... – Aubin

+0

Спасибо. Это уточняет мою ошибку. Я не понимал, что, как только «writeitem» выводится на «master», он все еще известен как «writeitem» WITHIN «master» и так изменен каждый раз. – lexipenia

Смежные вопросы