Как удалить дубликат ключа из Hashmap - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть список списка.Есть список в списке.[[-1, 0, 1], [-1, 2, -1], [0, 1, -1]], имя этого списка говорит результат.Список результатов содержит повторяющиеся элементы в виде списка.[-1,0,1] и [0,1,-1] они одинаковы.Я хочу сделать список, который не содержит дубликатов.Таким образом, результатом списка становится [[-1,0,1],[-1,2,-1]] или [[-1,2,-1],[0,1,-1]].

. Я прочитал, что Hashmap не может хранить повторяющиеся ключи, но допускает повторяющиеся значения.Таким образом, чтобы удалить дубликаты, я пытался Hashmap.

Но после написания кода он работает хорошо, ошибок нет.

HashMap<List<Integer>,Integer> final_sol=new HashMap<>();
for(int k1=0;k1<result.size();k1++){
       final_sol.put(result.get(k1),k1);
    }
    System.out.println(final_sol);

Вывод:

{[-1, 2, -1]=1, [0, 1, -1]=2, [-1, 0, 1]=0}

После записиэтот код блокирует. Я думал, что мои дублирующиеся ключи не могут отображать только отображаемые уникальные ключи.

Тогда как я могу сделать этот список уникальным, используя карту хеширования? Не понять

Когда яиспользовала древовидную карту, она не компилируется и выдала ошибку.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Попробуйте что-то вроде этого:

List<List<Integer>> result = Arrays.asList(
      Arrays.asList(-1, 0, 1),
      Arrays.asList(-1, 2, -1),
      Arrays.asList(0, 1, -1)
);
HashMap<Set<Integer>, List<Integer>> final_sol = new HashMap<>();

for (List<Integer> list : result) {
  final_sol.put(new HashSet<>(list), list);
}

System.out.println(final_sol.values());

Вы думаете, что [-1,0,1] и [0,1,-1] они одинаковы, но это не относится к спискам, потому что порядок элементов имеет значение.Вам нужны наборы для этого понимания равных.

Но даже тогда это может быть не так, как вы ожидали, когда [0,0,1] и [0,1,1] одинаковы.В этом случае вы должны преобразовать каждый список в карту, которая дает вам счет того же Integer в исходном списке.

0 голосов
/ 02 февраля 2019

Похоже, что вы можете сделать это в режиме онлайн с Set<Set<Integer>>.Это дает вам [[-1, 0, 1], [-1, 2]];гомоморфен [[-1, 0, 1], [-1, 2, -1]], но не желаемый результат.Следующее предназначено для набора векторов из трех целых чисел, которые сравниваются равными с любой перестановкой, что согласуется с вашими примерами.Согласно документации , для переопределения equals требуется отношение эквивалентности и обязательно hashCode, такое, что a == b -> hashCode(a) == hashCode(b).

import java.lang.String;
import java.lang.Integer;
import java.util.Set;
import java.util.LinkedHashSet;

class Java {

    public static void main(String args[]) {
        Set<Three> set = new LinkedHashSet<>();
        set.add(new Three(-1, 0, 1));
        set.add(new Three(-1, 2, -1));
        set.add(new Three(0, 1, -1));
        System.out.printf("%s.\n", set);
    }

}

final class Three {
    private int a, b, c;
    public Three(final int a, final int b, final int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    @Override
    public int hashCode() { return a + b + c; }
    @Override
    public boolean equals(Object o) {
        if(this == o) return true;
        if(!(o instanceof Three)) return false;
        Three t = (Three)o;
        /* Brute force 3! = 6. */
        return a == t.a && b == t.b && c == t.c
            || a == t.a && b == t.c && c == t.b
            || a == t.b && b == t.a && c == t.c
            || a == t.b && b == t.c && c == t.a
            || a == t.c && b == t.a && c == t.b
            || a == t.c && b == t.b && c == t.a;
    }
    @Override
    public String toString() {
        return "["+a+","+b+","+c+"]";
    }
}

.

[[-1,0,1], [-1,2,-1]].

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

    /** Hashcode is the sum of the unique numbers. */
    @Override
    public int hashCode() {
        int h = a;
        if(a != b) h += b;
        if(c != a && c != b) h += c;
        return h;
    }
    @Override
    public boolean equals(Object o) {
        if(this == o) return true;
        if(!(o instanceof Three)) return false;
        Three t = (Three)o;
        /* t \in this && this \in t. */
        return (a == t.a || a == t.b || a == t.c)
            && (b == t.a || b == t.b || b == t.c)
            && (c == t.a || c == t.b || c == t.c)
            && (t.a == a || t.a == b || t.a == c)
            && (t.b == a || t.b == b || t.b == c)
            && (t.c == a || t.c == b || t.c == c);
    }
0 голосов
/ 02 февраля 2019

Это правда, что Карты не сохраняют дубликаты ключей, а Наборы не сохраняют дубликаты элементов, но вы должны понимать, что «дубликат» определяется в терминах методов / ключей equals(), и что коллекции на основе хеш-функции зависятна их ключах / элементах, имеющих hashCode() методы, которые соответствуют их equals() методам.

Теперь вы говорите

[-1,0,1] и [0,1,-1] они одинаковы.

, но нет, они не - то же самое, что и определение равенства List s.Порядок элементов списка является значительным, и списки должны реализовывать equals() таким образом, чтобы это отражать.Вот почему оба этих списка могут отображаться в виде ключей в одном и том же Map, и оба могут отображаться в виде элементов в одном и том же Set.

Тогда как я могу сделать этот список уникальным с помощью Hash map?

Очевидно, заказ не важен для ваших целей, поэтому List s не совсем подходящая модель для вас.Если вам не нужно размещать дубликаты элементов, вам следует рассмотреть возможность использования наборов.Стандартная библиотека предоставляет несколько реализаций, из которых HashSet, вероятно, будет наиболее подходящим для вашей ситуации, насколько я понимаю.Если вам do необходимо разместить дубликаты элементов, то вы ищете мультимножество.Стандартная библиотека не обеспечивает реализацию, но есть несколько доступных от третьих лиц.

Когда я использовал древовидную карту, она не компилируется и выдает некоторую ошибку.

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

В целом, вместо списка списков вам нужен набор множеств или набор мультимножеств.Я не понимаю, почему вы захотите принести в него карты.

...