Как проверить, является ли список ключом в hashmap?

#java #list #hashmap #key-value

Вопрос:

У меня есть карта от списка до строки (ключи-это списки). ключи преобразуются из массивов int в списки. добавление примера пары:

 int[] arr = { 1, 2, 3, 4, 5 };
my_map.put(Arrays.asList(arr), "12345");
 

Теперь, когда я проверяю, содержит ли my_map какой-либо другой список, я всегда буду получать значение null, например:

 int[] test_arr = { 1, 2, 3, 4, 5 };

if (my_map.get(Arrays.asList(test_arr)) != null) { // always null!

// do something

}
 

Я знаю, в чем проблема: это сравнение адресов списков, а НЕ значений!

Как я могу сравнить значения этих списков ?

Ответ №1:

Проблема, о которой вы упомянули, верна, я предложу заменить значение ключа строкой в списке. Но если вы настаиваете по своим причинам, вы можете включить реализацию списка в свой собственный класс и переопределить функцию «равно», основанную на значениях, а не на адресе.

Комментарии:

1. Спасибо. наконец, я заменил ключ на строку (вместо списка) и использовал «равно» для сравнения ключей.

Ответ №2:

Некоторые реализации карт позволяют создавать экземпляры вашей карты с помощью компаратора (например, карта деревьев).

Таким образом, вы можете предоставить свою собственную реализацию, чтобы определить, равны ли Ключи. Ваша функция компаратора возвращает значение int со значением, которое больше нуля, меньше нуля или равно нулю, если два значения равны.

Ответ №3:

Мой совет-немного изменить хранилище, чтобы иметь ту же функциональность. Означает проверку наличия предопределенного списка в структуре. Вам не нужно Map , так как добавлять значения не требуется, просто используйте значения внутри List . Дальше больше пользы Objects и не primitives будет . Вкратце а List of Lists хорошо подойдет в этом случае. Обратите внимание, порядок элементов в List вопросах. Если вас не волнует порядок, вы можете просто отсортировать оба списка перед сравнением.

 public class TestListArr {

    public static void main(String[] args) {
    
        List<List<Integer>> list = new ArrayList<>();
        Integer[] arr = { 1, 2, 3, 4, 5 };
        //just check it
        //int[] arr1 = {1,2,3};
        //Arrays.asList(arr1).forEach(System.out::println);
        //Arrays.asList(arr).forEach(System.out::println);
        list.add(Arrays.asList(arr));
        Integer[] test_true = { 1, 2, 3, 4, 5 };
        System.out.println(check(list,test_true));
        Integer[] test_false = { 1, 2, 3, 4 };
        System.out.println(check(list,test_false));
        //direct test
        //System.out.println(Arrays.asList(arr).equals(Arrays.asList(test_true)));
    }
    
    public static boolean check(List<List<Integer>> list, Integer[] test)
    {
        for(List<Integer> lst:list)
        {
            if(lst.equals(Arrays.asList(test)))
                return true;
        }
        return false;
    }

}
 

Выход

 true
false
 

Ответ №4:

List Объекты, которые вы создаете, содержат только один элемент, объект типа int[] . int[] использует идентификатор для проверки равенства, а не содержимого массива. Вместо этого преобразуйте содержимое массива в список с эквивалентным содержимым:

 static List<Integer> toList(int[] arr) {
    return IntStream.of(arr).boxed().collect(Collectors.toList());
}