вопрос
В настоящее время интернет -технология зрелая, и все больше и больше, как правило, децентрализованы, распределенные и потоковые вычисления, что ставит много вещей, которые были сделаны на стороне базы данных на стороне Java. Сегодня кто -то спросил, если в поле базы данных нет индекса, как это должно быть дедуплистским на основе поля? Все соглашаются использовать Java, чтобы сделать это, но как это сделать?
отвечать
Внезапно я вспомнил статью, которую я написал в списке, чтобы удалить тяжелые тяжелые веса, и нашел ее и прочитал. Метод состоит в том, чтобы переписать хэшкод и равен методам объекта в списке, бросить его в хэшсет, а затем вывести его. Это ответ, который я записал как словарь, когда впервые выучил Java. Например, при проведении собеседования люди, которые были в Java в течение 3 лет, они могут запомнить разницу между набором и HashMap, но они не знают, как ее реализовать. Другими словами, новички только запоминают характеристики. Но когда вы на самом деле используете его в проекте, вам нужно убедиться, что это правда. Поскольку одобрение бесполезно, я могу только в результат. Вы должны знать, как хешет помогает мне удалить тяжелый вес. Если вы думаете об этом, можете ли вы удалить тяжелую нагрузку без хешса? Самый простой и самый прямой способ - это сравнивать его с историческими данными каждый раз и вставлять его в хвост очереди, если он отличается. И хэшст просто ускоряет этот процесс.
Во -первых, дайте пользователю объекта сортировку
@Data@builder@allargscstrontruprupruppublic class user {private Integer id; private String name;} list <user> users = lists.newarraylist (новый пользователь (1, «a»), новый пользователь (1, «b»), новый пользователь (2, «b»), новый пользователь (1, «a»));Цель состоит в том, чтобы вывести пользователя без дубликата идентификатора. Чтобы предотвратить ссору, я даю правилу. Просто возьмите данные с уникальными идентификаторами по желанию, и не обязательно должны быть добросовестными, какая из них рассчитывается, когда идентификатор такой же.
Используйте наиболее интуитивно понятный метод
Этот метод состоит в том, чтобы использовать пустой список для хранения обходных данных.
@Testpublic void dis1 () {list <user> result = new LinkedList <> (); для (пользователь пользователя: пользователи) {boolean b = result.stream (). AnyMatch (u -> u.getId (). Equals (user.getId ())); if (! b) {result.add (user); }} System.out.println (result);}Используйте хэшсет
Любой, кто запомнил функции, знает, что хэшсет может удалить тяжелые веса, так как мне удалить тяжелые веса? Запомните это немного глубже и в соответствии с хэшкодом и равными методами. Так как же это основано на этих двух? Люди, которые не читали исходный код, не могут продолжаться, и интервью заканчивается здесь.
На самом деле, Hashset реализуется HashMap (я никогда не видел исходного кода, и я всегда интуитивно думал, что ключ хэшмапа реализован Hashset, который является точно наоборот). Я не буду расширять описание здесь, просто посмотрите на метод строительства и добавьте метод хэшса, чтобы понять.
public hashset () {map = new hashmap <> ();}/*** Очевидно, что если он существует, он возвращает false, если он не существует, он возвращает true*/public boolean add (e e) {return map.put (e, настоящий) == null;}Затем из этого также можно увидеть, что повторение хешса реализовано на основе HashMap, а реализация HashMap полностью зависит от методов HashCode и Equal. Теперь он полностью открыт. Если вы хотите использовать хэшсет, вы должны быть оптимистично с оптимизмом о своих двух методах.
В этом вопросе нам нужно дедупликации на основе идентификатора, поэтому наша основание сравнения является идентификатором. Модификации следующие:
@OverridePublic boolean equals (Object o) {if (this == o) {return true; } if (o == null || getClass ()! = o.getClass ()) {return false; } Пользователь пользователь = (пользователь) o; return objects.equals (id, user.id);}@overridepublic int hashcode () {return objects.hash (id);} // hashcoderesult = 31 * result + (element == null? 0: element.hashcode ());Среди них объекты вызывает хэшкод массивов, а содержание, как показано выше. Умножьте на 31 равна x << 5-х.
Окончательная реализация заключается в следующем:
@Testpublic void dis2 () {set <user> result = new Hashset <> (users); System.out.println (result);}Используйте Java Stream для дедупликации
Возвращаясь к первоначальному вопросу, причина задания этого вопроса заключается в том, что если вы хотите повторно поместить сторону базы данных на сторону Java, объем данных может быть относительно большим, например, 100 000 штук. Для больших данных использование функций, связанных с потоком, является самым простым. Точно так же, как поток также обеспечивает четкую функцию. Так как это следует использовать?
users.parallelstream (). instist (). foreach (system.out :: println);
Я не видел Lambda как параметр, то есть никаких пользовательских условий не было. К счастью, Javadoc отметил стандарт дедупликации:
Возвращает поток, состоящий из различных элементов (в соответствии с {@link объектом#equals (object)}) этого потока.Мы знаем, что мы также должны запомнить этот принцип: когда равняется верно, возвращаемое значение хэшкода должно быть одинаковым. Это немного логически запутанно при запоминании, но пока мы понимаем метод реализации Hashmap, нам не будет трудно говорить. HashMap сначала находит в соответствии с методом HashCode, а затем сравнивает метод Equals.
Следовательно, чтобы использовать отдельные для достижения дедупликации, вы должны переопределить методы HashCode и равен, если вы не используете по умолчанию.
Итак, почему вы это делаете? Нажмите и посмотрите на реализацию.
<P_IN> Узел <T> уменьшить (PipelineHelper <T> Helper, Spliterator <P_IN> Spliterator) {// Если поток сортирован, его также следует заказать, поэтому следующее также // Сохранить порядок сортировки <T, linkedHashset <T>> REDUSTOPS. LinkedHashset :: Add, LinkedHashset :: Addall); return nodes.node (dreamop.evaluateparallel (helper, splitterator));}Внутренняя реализация достигается путем сокращения. Когда вы думаете о уменьшении, вы сразу же думаете о методе для реализации различий сами. Мне просто нужно использовать уменьшение, и часть расчета состоит в том, чтобы сравнить элементы потока со встроенной HashMap, пропустить их, если есть, и поместите их, если нет. На самом деле, идея является самым простым методом в начале.
@Testpublic void dis3 () {users.parallelstream (). Filter (instistbykey (user :: getId)) .foreach (system.out :: println);} public static <t> предикат <t> endienceBykey (function <? Super T,?> KeyExtractor) {set <bheat> see = complyShamap.NewKeySet (); return t -> see.add (keyextractor.apply (t));}Конечно, если это параллельный поток, тот, который взят, не обязательно является первым, но является случайным.
Вышеуказанный метод является лучшим и неинвазивным. Но если вам нужно использовать различные. Вы можете переписать только хэшкод и равны, как метод хэшса.
краткое содержание
Вы можете только практиковать, можете ли вы использовать эти вещи сами. В противном случае, будет трудно вырвать их одновременно, когда вы действительно захотите их использовать, или вы будете рисковать. И если вы действительно хотите использовать его смело, также необходимо понять правила и принципы реализации. Например, как отличаются реализации LinkedHashset и Hashset?
Прикреплено с простым исходным кодом LinkedHashset:
открытый класс LinkedHashset <e> расширяет хэшсет <e> реализует набор <e>, клонируемый, java.io.serializable {private static final long long serialversionuid = -2851667679971038690l; public linkedHashset (int initialCapacity, float loadFactor) {super (initialCapacity, loadfactor, true); } public linkedHashset (int initialCapacity) {super (initialCapacity, .75f, true); } public linkedHashset () {super (16, .75f, true); } public LinkedHashset (Collection <? Extends E> C) {super (math.max (2*c.size (), 11), .75f, true); addall (c); } @Override public spliterator <e> spliterator () {return spliterators.spliterator (это, spliterator.sistinct | spliterator.ordered); }}Пополнить:
Метод удаления дублирующих данных из сбора списков в Java
1. Целью все элементы в списке, а затем удаляйте дубликаты
Общедоступный статический список удаленного (список) {for (int i = 0; i <list.size () - 1; i ++) {for (int j = list.size () - 1; j> i; j -) {if (j). }}} return List; } 2. Начните дублирующие элементы через хэшсет
Общедоступный статический список удаленного (список) {hashset h = new Hashset (List); list.clear (); list.addall (h); вернуть список; }3. Удалить дублируемые элементы в ArrayList, чтобы сохранить заказ
// Удалить дублируемые элементы в ArrayList, сохраните заказ public void elementuplicateWithOrder (список списков) {set set = new hashset (); Список newlist = new ArrayList (); for (iterator iter = list.iterator (); iter.hasnext ();) {object element = iter.next (); if (set.add (element)) newlist.add (element); } list.clear (); list.addall (newlist); System.out.println ("удалить дубликат" + list); }4. Итерация над объектом в списке, используйте list.contain (), и если он не существует, поместите его в другую коллекцию списков.
public Static List elementuplicate (список) {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; }