pregunta
Hoy en día, la tecnología de Internet es madura, y cada vez más tienden a descentralizar, distribuirse y transmitir la informática, lo que ha puesto muchas cosas que se han hecho en el lado de la base de datos en el lado de Java. Hoy, alguien preguntó, si el campo de la base de datos no tiene un índice, ¿cómo debe dedicarse en función del campo? Todos aceptan usar Java para hacerlo, pero ¿cómo hacerlo?
respuesta
De repente, recordé el artículo que escribí en la lista para eliminar pesas pesadas antes, y lo encontré y lo leí. El método es reescribir el hashcode e igualar los métodos del objeto en la lista, tirarlo al hashset y luego sacarlo. Esta es la respuesta que escribí como un diccionario cuando aprendí por primera vez a Java. Por ejemplo, al entrevistar, las personas que han estado en Java durante 3 años, pueden memorizar la diferencia entre Set y HashMap, pero no saben cómo implementarlo. En otras palabras, los principiantes solo memorizan las características. Pero cuando realmente lo usa en un proyecto, debe asegurarse de que sea cierto. Debido a que el respaldo es inútil, solo puedo creer en el resultado. Necesita saber cómo Hashset me ayuda a eliminar el peso pesado. Si lo piensa, ¿puede eliminar la carga pesada sin hashset? La forma más simple y directa es compararlo con datos históricos cada vez e insertarlos en la cola de la cola si es diferente. Y Hashset simplemente acelera este proceso.
Primero, dale al usuario del objeto a clasificar
@Data@builder@AllargSconstructorPublic Class User {private entero ID; Nombre de cadena privada;} list <ser User> users = lists.newarrayList (nuevo usuario (1, "A"), nuevo usuario (1, "B"), nuevo usuario (2, "B"), nuevo usuario (1, "A"));El objetivo es eliminar al usuario sin identificación duplicada. Para evitar la disputa, doy una regla. Simplemente saque datos con IDS únicos a voluntad, y no tiene que ser consciente de cuál se calcula cuando la ID es la misma.
Use el método más intuitivo
Este método es usar una lista vacía para almacenar los datos atravesados.
@Testpublic void dis1 () {list <serer> result = new LinkedList <> (); for (usuario de usuario: usuarios) {boolean b = result.stream (). AnyMatch (u -> u.getid (). Equals (user.getID ())); if (! b) {result.add (usuario); }} System.out.println (resultado);}Usar hashset
Cualquiera que haya memorizado las características sabe que hashset puede eliminar pesas pesadas, entonces, ¿cómo elimino pesas pesadas? Memorícelo un poco más profundo y de acuerdo con el hásido y es igual a los métodos. Entonces, ¿cómo se basa en estos dos? Las personas que no han leído el código fuente no pueden continuar, y la entrevista termina aquí.
De hecho, HashSet es implementado por HashMap (nunca he visto el código fuente y siempre he pensado intuitivamente que la clave de HashMap es implementada por Hashset, que es exactamente lo contrario). No ampliaré la descripción aquí, solo mire el método de construcción y agregue el método de hashset para comprender.
public Hashset () {map = new Hashmap <> ();}/*** Obviamente, si existe, devuelve falso, si no existe, devuelve verdadero*/public boolean add (e e) {return map.put (e, presente) == NULL;}Luego, también se puede ver a partir de esto que la repetición de HashSet se implementa en función de HashMap, y la implementación de HashMAP se basa por completo en el CODED y es igual a los métodos. Ahora está completamente abierto. Si desea usar Hashset, debe ser optimista sobre sus dos métodos.
En esta pregunta, necesitamos deduplicar en función de ID, por lo que nuestra base de comparación es ID. Las modificaciones son las siguientes:
@OverridePublic boolean es igual (objeto o) {if (this == o) {return true; } if (o == null || getClass ()! = O.getClass ()) {return false; } Usuario user = (usuario) o; return Objects.equals (id, user.id);}@overRidePublic int hashcode () {return Objects.hash (id);} // hashcoderesult = 31 * resultado + (element == null? 0: element.hashcode ());Entre ellos, los objetos llaman al hashcode de matrices, y el contenido es como se muestra arriba. Multiplicar por 31 es igual a x << 5-x.
La implementación final es la siguiente:
@TestPublic void dis2 () {set <serer> result = new Hashset <> (usuarios); System.out.println (resultado);}Use la transmisión Java para deduplicar
Volviendo a la pregunta inicial, la razón para hacer esta pregunta es que si desea volver a realizar el lado de la base de datos al lado de Java, la cantidad de datos puede ser relativamente grande, como 100,000 piezas. Para Big Data, usar funciones relacionadas con la corriente es la más fácil. Así como Stream también proporciona la función distinta. Entonces, ¿cómo se debe usar?
Users.ParallelStream (). Distint (). foreach (System.out :: println);
No vi a Lambda como un parámetro, es decir, no se proporcionaron condiciones personalizadas. Afortunadamente, Javadoc marcó el estándar de deduplicación:
Devuelve una secuencia que consta de los elementos distintos (según {@link Object#iguales (objeto)}) de esta transmisión.Sabemos que también debemos memorizar este principio: cuando igualmente devuelve verdadero, el valor de retorno de hashcode debe ser el mismo. Esto es un poco confuso lógicamente al memorizar, pero mientras entendamos el método de implementación de Hashmap, no nos sentiremos difíciles de hablar. Hashmap primero se ubica de acuerdo con el método hashcode, y luego compara el método igual.
Por lo tanto, para usar distintos para lograr la deduplicación, debe anular el hostil y igual a los métodos a menos que use el predeterminado.
Entonces, ¿por qué haces esto? Haga clic y eche un vistazo a la implementación.
<p_in> nodo <t> reduce (PipelineHelper <T> Helper, Spliterator <P_in> Splititerator) {// Si la transmisión está ordenada, entonces también se debe ordenar para que lo siguiente // preservará el orden terminalp <t, Linkedhashset <t>> reduce = reduceps. <T, Linkedhashhash <t>> Makeref (Linkedhashset :: ninkedhashset <t>, reduce = reduce. Linkedhashset :: add, Linkedhashset :: addall); return nodos.node (rededop.evaluateParallel (ayudante, divisorador));}La implementación interna se logra reduciendo. Cuando piensas en reducir, piensas instantáneamente en un método para implementar distintivos por ti mismo. Solo necesito usar Reduce, y la parte de cálculo es comparar los elementos de la corriente con un hashmap incorporado, omitirlos si lo hay y ponerlos si no hay. De hecho, la idea es el método más directo al principio.
@Testpublic void dis3 () {users.parallelStream (). Filter (distintyKey (user :: getId)) .ForEach (system.out :: println);} public static <t> predicate <t> distintykey (function <? Super t,?> KeyExtractor) {set <pect> ver = concurrenthashmap.newkeSet ();); return t -> ver.add (keyExtractor.apply (t));}Por supuesto, si es una corriente paralela, la que se toma no es necesariamente la primera, sino que es aleatoria.
El método anterior es el mejor encontrado y no es invasivo. Pero si tienes que usar distinto. Solo puede reescribir hashcode e igual al método hashset.
resumen
Solo puedes practicar si puedes usar estas cosas tú mismo. De lo contrario, será difícil sacarlos de inmediato cuando realmente desee usarlos, o se arriesgará. Y si realmente desea usarlo con valentía, también es necesario comprender las reglas y los principios de implementación. Por ejemplo, ¿en qué se diferencian las implementaciones de Linkedhashset y Hashset?
Adjunto con el simple código fuente de Linkedhashset:
La clase pública Linkedhashset <E> extiende el conjunto de hashset <E> SET <E>, Clonable, java.io.serializable {private estático final long SerialverSionUid = -2851667679971038690l; public Linkedhashset (int InitialCapacity, Float LoadFactor) {super (InicialCapacity, LoadFactor, True); } public Linkedhashset (int InitialCapacity) {super (InicialCapacity, .75f, true); } public LinkedHashSet () {super (16, .75f, true); } public Linkedhashset (colección <? extiende e> c) {super (math.max (2*c.size (), 11), .75f, true); addall (c); } @Override public splititerator <E> spliterator () {return Splitriterators.spliterator (this, Splitriter.Distinct | Spliterator.Ordered); }}Reponer:
Método para eliminar datos duplicados de la recopilación de listas en Java
1. Lise todos los elementos en la lista y luego elimine los duplicados
Public static List eliminados (lista de listas) {for (int i = 0; i <list.size () - 1; i ++) {for (int j = list.size () - 1; j> i; j -) {if (list.get (j) .equals (list.get (i))) {list.remove (j); }}} Lista de retorno; } 2. Comience los elementos duplicados a través de Hashset
Lista estática pública eliminada (lista de listas) {hashset h = new Hashset (lista); list.clear (); list.addall (h); lista de devolución; }3. Eliminar elementos duplicados en ArrayList para mantener el orden
// Eliminar elementos duplicados en ArrayList, mantenga el orden público estático void eliminado UplicateWithorder (list list) {set set = new Hashset (); List NewList = new ArrayList (); for (iterator iter = list.iterator (); iter.hasnext ();) {objeto elemento = iter.next (); if (set.add (elemento)) newList.Add (elemento); } list.clear (); list.addall (NewList); System.out.println ("eliminar duplicado" + lista); }4. Iterer sobre el objeto en la lista, use list.contain (), y si no existe, póngalo en otra colección de listas.
Public static List eliminedUpLicate (List List) {List listTemp = new ArrayList (); for (int i = 0; i <list.size (); i ++) {if (! listtemp.contains (list.get (i))) {listtemp.add (list.get (i)); }} return listTemp; }