Древовидная карта<строка,(новая древовидная карта()) Древовидная карта с объектом

#java #collections #treemap

#java #Коллекции #древовидная карта

Вопрос:

Привет, у меня есть следующий код

 TreeMap mp = new TreeMap<String,TreeMap<String,Integer>();
mp.put(line,(new TreeMap<String,Integer>()));
 

Теперь, если я хочу вставить данные в новое пустое дерево <Строка, целое число>, созданное «mp», как мне это сделать?

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

1. Какой тип mp ? Что такое EmptyTree ? Вы имели в виду TreeMap ?

Ответ №1:

Существует множество способов сделать это.

Во-первых, вы могли бы просто сохранить ссылку вокруг:

 var map = new TreeMap<String,Integer>();
mp.put(line, map);
// can du stuff with map now
 

Во-вторых, вы можете прочитать значение обратно с карты — очевидно, это не очень эффективно, но я бы включил его для полноты картины:

 mp.put(line,(new TreeMap<String,Integer>()));
var map = mp.get(line);
 

Самым элегантным решением было бы использовать computeIfAbsent :

 var map = mp.computeIfAbsent(line, line -> new TreeMap<String,Integer>());
// do stuff with map
 

computeIfAbsent возвращает значение, которое уже присутствует на карте, или иным образом вычисляет лямбда-выражение и помещает его в карту, и возвращает это значение.

Из JavaDoc:

Если указанный ключ еще не связан со значением (или сопоставлен null ), пытается вычислить его значение с помощью заданной функции сопоставления и вводит его в эту карту, если null .

Если функция сопоставления возвращает значение null, сопоставление не записывается. Если функция сопоставления сама выдает (непроверенное) исключение, исключение повторно отбрасывается, и сопоставление не записывается. Наиболее распространенным использованием является создание нового объекта, служащего в качестве начального отображенного значения или запоминаемого результата, как в:
map.computeIfAbsent(key, k -> new Value(f(k)));

Или реализовать многозначную карту Map<K,Collection<V>> , поддерживающую несколько значений для каждого ключа:
map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);

Функция отображения не должна изменять эту карту во время вычисления

Преимущество computeIfAbsent заключается в том, что вам не нужно проверять, присутствует ли значение уже на карте, и нет опасности переопределения старых значений.

Ответ №2:

Извлеките его с помощью TreeMap#get(java.lang.Object) и поместите значение, используя один из методов put из извлеченного TreeMap , например TreeMap#put(K, V) .

Пример:

 // notice the diamond operator used here -- it improves your code readability!!
TreeMap<String,TreeMap<String,Integer>> mp = new TreeMap<>();

// you don't need to qualify the type again because of the diamond operator
mp.put(line, new TreeMap<>());

// put a new value into the newly created TreeMap
Integer value = 1;
mp.get(line).put("your string key", value);
 

Для полноты картины: если вы используете Java 8 или новее, чтобы сделать код еще более чистым, вы можете использовать computeIfAbsent :.

 TreeMap<String,TreeMap<String,Integer>> mp = new TreeMap<>();

Integer value = 1;
mp.computeIfAbsent(line, key -> new TreeMap<>()).put("your string key", value);
 

Ответ №3:

Опубликованный вами фрагмент кода имеет несколько проблем:

 TreeMap mp = new TreeMap<String,TreeMap<String,Integer>();
       ^ add type specifier                           ^missing `>`
 

В первой строке вы не указали общий тип, поэтому ваш mp тип является rawtype — поэтому вызов get на нем возвращает что-то типа Object — для использования этого потребуется приведение, и это не рекомендуется. Допустимыми версиями являются:

 TreeMap<String,TreeMap<String,Integer>> mp = new TreeMap<>();
 

или

 var mp = new TreeMap<String,TreeMap<String,Integer>>();
 

обе эти версии позволяют вам получать доступ к вложенным картам без приведений:

 TreeMap<String, Integer> m = mp.get(line);
 

Но, как уже упоминали другие, поместить значение в map в случае, если оно отсутствует, но использовать существующее значение в противном случае — это именно то, для чего предназначен метод computeIfAbsent — использование, которое вы можете написать, например:

     var line = "line";      
    var mp = new TreeMap<String,TreeMap<String,Integer>>();     
    var m = mp.computeIfAbsent(line, k -> new TreeMap<>());
    m.put("content", 5);
    System.out.println(mp);
 

Выходной сигнал:

 {line={content=5}}