2012-03-29 54 views
13

Lo arreglé en realidad. Aquí está mi nuevo código.Restando un arrayList de otro arrayList

//returns a new IntSet after subtracting a from b 
// .minus().toString() 
ArrayList<Integer> minusArray = new ArrayList<Integer>(); 

    minusArray.addAll(array1); 

    for(int i =0; i< minusArray.size(); i++){ 
     for(int j = 0; j < array2.size(); j++){ 
      if(minusArray.get(i).equals(array2.get(j))){ 
       minusArray.remove(i); 
       if(i == 0){ 
        ; 
       } 
       else if(j == 0){ 
        ; 
       } 
       else{ 
        i = 0; 
        j = 0; 
       } 
      } 
      else{} 
     } 
    } 

return minusArray; 

Tengo dos arrayLists y estoy tratando de "restar" una lista de arreglos de otra. Por ejemplo, si tengo un arrayList [1,2,3] y estoy tratando de restar [0, 2, 4], el arrayList resultante debe ser [1,3].

Mi código funciona en algunos casos, como si arrayList1 = [4,6] y arrayList2 = [6] me dará un resultado de [4]. Pero si intento algo así como [1,2,4] y [0,4,8]

consigo esta excepción:

java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 
    at java.util.ArrayList.rangeCheck(Unknown Source) 
    at java.util.ArrayList.get(Unknown Source) 
    at IntSet.minus(IntSet.java:119) 
    at IntSetDriver.main(IntSetDriver.java:62) 

Este es el código que he llegado con. He hecho pruebas y creo que debería funcionar. El usuario ingresa estas listas de arreglos y las clasifica, tampoco conozco Hash o big-O.

ArrayList<Integer> minusArray = new ArrayList<Integer>(); 

    minusArray.addAll(array1); 

    for(int i =0; i< minusArray.size(); i++){ 
     for(int j = 0; j < array2.size(); j++){ 
      if(minusArray.get(i).equals(array2.get(j))){ 
       minusArray.remove(i); 
      } 
      else{} 
     } 
    } 

return minusArray; 

Respuesta

2

Su problema es que en su minusArray.remove (...) llama puede reducir el tamaño de la minusArray. Para solucionar esto, comience en array.size() - 1 y cuente hacia atrás en 0

Compruebe eso, incluso eso no lo solucionará. Debe invertir el orden de sus bucles

28

Intente utilizar el método de resta de la clase org.apache.commons.collections.CollectionUtils.

Devuelve una nueva Colección que contiene a - b. La cardinalidad de cada elemento e en la Colección devuelta será la cardinalidad de e en a menos la cardinalidad de e en b, o cero, el que sea mayor.

CollectionUtils.subtract (java.util.Collection una, java.util.Collection b)

De Apache Commons Collections

+0

¿Qué es CS 251? – kukis

+2

@kukis CS 251 será un curso de informática de segundo año en alguna universidad. –

2

supongo que obtiene el problema rango debido a que ha eliminado uno de los elementos que cambia lo que el lazo interno está buscando (sé que este problema ocurre cuando se trata de listas y colecciones normales).

Lo que he tenido que hacer en el pasado para solucionar este problema, es crear una lista de elementos que deben eliminarse (es decir, los que se encuentran en la lista original). Itere a través de esa nueva lista y elimine directamente los elementos de la lista original sin tener que tener un iterador moviéndose a través de ella.

6

Recorrido de la minusArray utilizando un índice es una manera de hacer esto, pero le sugiero que haga uso del método contains(Object), lo que le permitirá a continuación, utilizar remove(Object) para el elemento particular de array2.

Por supuesto, siempre existe la removeAll(Collection), que hace casi todo lo que necesita ...

+0

+1 para la forma "normal" de hacer esto. –

4

Puede utilizar org.apache.commons.collections.ListUtils y hacer todo lo que desee en una sola línea =)

List resultList = ListUtils.subtract(list, list2); 
22

¿hay alguna razón no se puede simplemente usar List.removeAll (Lista)?

List<Integer> one = new ArrayList<Integer>(); 
    one.add(1); 
    one.add(2); 
    one.add(3); 
    List<Integer> two = new ArrayList<Integer>(); 
    two.add(0); 
    two.add(2); 
    two.add(4); 
    one.removeAll(two); 
    System.out.println(one); 

    result: "[1, 3]"