2009-08-05 34 views
12

Esto es principalmente una cuestión de rendimiento. Tengo una lista maestra de todos los usuarios que existen en una matriz de cadenas AllUids. También tengo una lista de todos los usuarios con fecha de finalización que existen en una matriz String EndUids.Java: comparando dos matrices de cadenas y eliminando los elementos que existen en ambas matrices

Estoy trabajando en Java y mi objetivo es eliminar cualquier usuario que exista en la matriz de fecha final de la lista maestra AllUids. Sé que PHP tiene una función llamada array_diff.

Tenía curiosidad si Java tiene algo que pueda comparar dos matrices y eliminar elementos que sean similares en ambas. Mi objetivo es el rendimiento aquí, por eso le pregunté sobre una función incorporada. No quiero agregar ningún paquete especial.

Pensé en escribir una función recursiva, pero parece que será ineficiente. Hay miles de usuarios en ambas listas. Para existir en la lista de fecha de finalización, debe existir en la lista AllUids, es decir, hasta que se elimine.

Ejemplo:

String[] AllUids = {"Joe", "Tom", "Dan", "Bill", "Hector", "Ron"}; 

String[] EndUids = {"Dan", "Hector", "Ron"}; 

Funcionalidad Busco:

String[] ActiveUids = AllUids.RemoveSimilar(EndUids); 

ActiveUids se vería así:

{"Joe", "Tom", "Bill"} 

Gracias a todos, Obviamente, puede llegar a bucles pero no estoy seguro de que sea eficiente. Esto es algo que funcionará en las máquinas de producción todos los días.

Respuesta

13

Commons Collections tiene una clase llamada CollectionUtils y un método estático llamado removeAll que tiene una lista inicial y una lista de cosas para retirar de esa lista:

Collection removeAll(Collection collection, 
        Collection remove) 

Eso debería hacer lo que quiera siempre y cuando use las listas de usuarios en lugar de matrices. Puede convertir su matriz en una lista muy fácilmente con Arrays.asList() así que ...

Collection ActiveUids = CollectionUtils.removeAll(Arrays.asList(AllUids), 
                Arrays.asList(EndUids)) 

EDIT: También hice un poco de excavación con esto en Commons Colecciones y encontré la siguiente solución con ListUtils en Colecciones Commons así:

Bastante limpio ...

+0

CollectionUtils no funcionó para mí, pero si me llama ActiveUids.removeall (EndUids), que funcionó a la perfección. Terminé cambiando la forma en que almacenaba las cuerdas. Creé un hashset usando lo siguiente: HashSet ActiveUids = new HashSet (); Gracias a todos por su ayuda. ¡Esto era exactamente lo que estaba buscando! – user84786

+0

Genial, creo que el modo ListUtils es mucho más limpio ... – Jon

+0

¿Se puede usar en Android? : S – Ewoks

5

no se puede "eliminar" los elementos de las matrices. Puede establecerlos como nulos, pero los arreglos son de tamaño fijo.

Usted podía uso java.util.Set y removeAll a tomar un juego de distancia de otro, pero prefiero usar el Google Collections Library:

Set<String> allUids = Sets.newHashSet("Joe", "Tom", "Dan", 
             "Bill", "Hector", "Ron"); 
Set<String> endUids = Sets.newHashSet("Dan", "Hector", "Ron"); 
Set<String> activeUids = Sets.difference(allUids, endUids); 

que tiene un ambiente más funcional a la misma.

+0

Una cosa que es un poco sorprendente acerca de este enfoque es que 'Sets.difference' devuelve * vista *. Si realmente quiere que 'activeUids' sea un' Set' normal (es decir, uno donde su valor no cambie si 'allUids' y' endUids' cambian, y cuando '' size() 'es O (1)), probablemente debería pasar inmediatamente el resultado de Sets.difference a algo que construye un Set. por ejemplo: 'Sets.newHashSet (Sets.difference (a, b))' –

1

En su lugar, podría poner esas cadenas en Collection y luego usar el método removeAll.

3

La solución más fácil es, probablemente, colocar todos los elementos en un conjunto y luego utilizar removeAll.Puede convertir a un conjunto de una matriz de esta manera:

Set<String> activeUids = new HashSet<String>(Arrays.asList(activeUidsArray)); 

aunque realmente debería tratar de evitar el uso de matrices y colecciones favor.

3

No use matrices para esto, use Collection y el método removeAll(). En cuanto a rendimiento: a menos que hagas algo estúpido que te lleve a O (n^2) tiempo de ejecución, olvídalo. Es una optimización prematura, el tipo inútil/dañino. "miles de usuarios" no es nada, a menos que lo haga miles de veces por segundo.

BTW, PHP "matrices" son de hecho mapas hash.

3
/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 

/** 
* 
* @author Bireswhar 
*/ 
import java.util.Collection; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

public class Repeated { 

    public static void main(String[] args) { 
//  Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta")); 
//  Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); 
// 
//  listOne.retainAll(listTwo); 
//  System.out.println(listOne); 

     String[] s1 = {"ram", "raju", "seetha"}; 
     String[] s2 = {"ram"}; 
     List<String> s1List = new ArrayList(Arrays.asList(s1)); 
     for (String s : s2) { 
      if (s1List.contains(s)) { 
       s1List.remove(s); 
      } else { 
       s1List.add(s); 
      } 
      System.out.println("intersect on " + s1List); 
     } 
    } 
} 
0
String s1 = "a,b,c,d"; 
    String s2 = "x,y,z,a,b,c"; 
    Set<String> set1 = new HashSet<String>(); 
    Set<String> set2 = new HashSet<String>(); 

    Set<String> set11 = new HashSet<String>(); 

    String[] splitS1 = s1.split(","); 
    String[] splitS2 = s2.split(","); 

    for(String s3:splitS1){ 
     set1.add(s3); 
     set11.add(s3); 
    } 

    for(String s4:splitS2){ 
     set2.add(s4); 
    } 
    set1.removeAll(set2); 
    set2.removeAll(set11); 
    set1.addAll(set2); 
    System.out.println(set1); 
+1

Se desaconseja la respuesta del código único. Es mejor explicar por qué y cómo este fragmento de código resuelve el problema – abarisone

Cuestiones relacionadas