У меня есть одна карта в java:
Map<String index1, Map<String index 2, Object obj>> map = new HashMap<>();
Я хочу получить Object
на карте с помощью index1
и index2
в качестве поисковых запросов.
У меня есть одна карта в java:
Map<String index1, Map<String index 2, Object obj>> map = new HashMap<>();
Я хочу получить Object
на карте с помощью index1
и index2
в качестве поисковых запросов.
Самый простой способ сделать это - использовать Guava Table
, если вы хотите использовать стороннюю библиотеку.
Он работает следующим образом:
Table<String, String, Object> table = HashBasedTable.create();
table.put(index1, index2, obj);
Object retrievedObject = table.get(index1, index2);
Вы можете добавить его в свой проект, выполнив следующие инструкции: Как добавить проект Guava в Eclipse
Если вы не хотите использовать Guava, у вас есть большая проблема. Если вы попытаетесь вставить элемент с новым первым ключом, вы должны убедиться, что сон уже существует. Это означает, что каждый раз, когда вы делаете put
, вы должны получить innerMap
, посмотреть, существует ли он, а затем создать его, если это не так. Вам нужно будет делать это каждый раз, когда вы вызываете Map.put
. Также вы рискуете выбросить NullPointerException
, если внутренняя карта не существует, когда вы вызываете get
на внутренней карте.
Если вы это сделаете, следует обернуть ваш Map<String, Map<String, Object>
во внешний класс для управления этими проблемами или использовать Java 8 computeIfAbsent
. Но самый простой способ - просто использовать Table
, как указано выше.
Если вы используете свой собственный класс вместо Table
, это будет примерно так:
public class DoubleMap<R, C, V> {
private final Map<R, Map<C, V>> backingMap;
public DoubleMap() {
this.backingMap = new HashMap<>();
}
public V get(R row, C column) {
Map<C, V> innerMap = backingMap.get(row);
if(map == null) return null;
else return innerMap.get(column);
}
public void put(R row, C column, V value) {
Map<C, V> innerMap = backingMap.get(row);
if(innerMap == null) {
innerMap = new HashMap<C, V>();
backingMap.put(row, innerMap);
}
innerMap.put(column, value);
}
}
Вы бы использовали этот класс, выполнив следующие действия:
DoubleMap<String, String, Object> map = new DoubleMap();
Обратите внимание, что этот ответ имеет намного меньше возможностей, чем версия Guava.
Map
Если я понимаю ваш вопрос, то с индексом a
и b
, который может выглядеть (защищая от null
с ternary или Условный оператор ? :
),
Object obj = (map.get("a") == null) ? null : map.get("a").get("b");
И вы можете быть более конкретным, например
Map<String, Map<String, Something>> map = new HashMap<>();
Something s = (map.get("a") == null) ? null : map.get("a").get("b");
Map
Предполагая, что вы хотите добавить Something value
к Map
, который может быть выполнен с помощью чего-то вроде
Map<String, Map<String, Something>> map = new HashMap<>();
if (map.get("a") == null) {
map.put("a", new HashMap<>());
}
map.get("a").put("b", value);
Если вам не нужен регулярный доступ ко всей "строке", а просто быстрый доступ к каждой ячейке, вы можете использовать встроенный Map.Entry
в качестве ключа:
Map<Map.Entry<String, String>, Object> table = new Map<>();
table.put(new Map.SimpleEntry("index1", "index2"), "Hello world");
В качестве альтернативы, если вы хотите пойти с чем-то сторонним, некоторые из них уже внедрили tuples для Java.
Если вы находитесь в ситуации, когда вы не можете легко загрузить стороннюю библиотеку, но вам не нравится семантика Map.Entry
(которая написана в терминах key
и value
s), вы может написать собственный класс Pair
, чтобы иметь тот же эффект.
Как я понимаю, вы можете сделать так:
Map<String, Map<String, Object> map= new HashMap();
Map<String, Object> subMap = map.get("index1");
if(subMap != null) {
Object obj = subMap.get("index2");
}
Лучшее решение, вероятно, зависит от того, как эта карта предназначена для использования:
String
или они должны быть общими?Прагматическое решение, сфокусированное на вопросе, как вы описали, будет представлять класс StringPair
, который можно использовать для индексирования. Это избавляет вас от необходимости выполнять 2D-поиск внутренних карт (и возможных очищений, когда внутренние карты становятся пустыми!), Не требует каких-либо сторонних библиотек и является читабельным и эффективным.
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
public class StringPairMapTest
{
public static void main(String[] args)
{
Map<StringPair, Object> map = new LinkedHashMap<StringPair, Object>();
map.put(StringPair.of("A","B"), 12);
map.put(StringPair.of("C","D"), 34);
System.out.println(map.get(StringPair.of("A","B")));
System.out.println(map.get(StringPair.of("C","D")));
System.out.println(map.get(StringPair.of("X","Y")));
}
}
class StringPair
{
private final String s0;
private final String s1;
static StringPair of(String s0, String s1)
{
return new StringPair(s0, s1);
}
private StringPair(String s0, String s1)
{
this.s0 = s0;
this.s1 = s1;
}
@Override
public String toString()
{
return "("+s0+","+s1+")";
}
@Override
public int hashCode()
{
return Objects.hash(s0, s1);
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StringPair other = (StringPair) obj;
return Objects.equals(s0, other.s0) && Objects.equals(s1, other.s1);
}
}
Конечно, возможны обобщения на Pair<T>
или Tuple<S,T>
, но это, похоже, не то, что вы искали...