Java - Как создать новую запись (ключ, значение)
Я хотел бы создать новый элемент, аналогичный Util.Map.Entry
, который будет содержать структуру key
, value
.
Проблема заключается в том, что я не могу создать экземпляр Map.Entry
, потому что это интерфейс.
Кто-нибудь знает, как создать новый универсальный объект key/value для Map.Entry?
Ответы
Ответ 1
Вы можете просто реализовать интерфейс Map.Entry<K, V>
самостоятельно:
import java.util.Map;
final class MyEntry<K, V> implements Map.Entry<K, V> {
private final K key;
private V value;
public MyEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
}
И затем используйте его:
Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
Ответ 2
Там public static class AbstractMap.SimpleEntry<K,V>
. Не позволяйте Abstract
части имени ввести вас в заблуждение: на самом деле это не класс Abstract
(но его верхний уровень AbstractMap
is).
Тот факт, что он вложенный класс static
означает, что вам не нужен экземпляр AbstractMap
для создания экземпляра, поэтому что-то вроде этого компилируется отлично:
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
Как отмечено в другом ответе, Guava также имеет удобный static
factory метод Maps.immutableEntry
, который вы можете использовать.
Ты сказал:
Я не могу использовать Map.Entry
сам, потому что, видимо, это объект только для чтения, который я не могу создать new instanceof
Это не совсем точно. Причина, по которой вы не можете создать экземпляр напрямую (т.е. С new
), состоит в том, что она interface Map.Entry
.
Предостережение и подсказка
Как указано в документации, AbstractMap.SimpleEntry
- @since 1.6
, поэтому, если вы застряли до 5.0, то он не доступен для вас.
Чтобы найти другой известный класс, который implements Map.Entry
, вы действительно можете перейти непосредственно к javadoc. Из версия Java 6
Интерфейс Map.Entry
Все известные классы реализации:
К сожалению, версия 1.5 не содержит список известных классов реализации, которые вы можете использовать, поэтому вы, возможно, застряли в реализации своих собственных.
Ответ 3
Попробуйте Maps.immutableEntry из Guava
Это имеет то преимущество, что оно совместимо с Java 5 (в отличие от AbstractMap.SimpleEntry
, для которого требуется Java 6.)
Ответ 4
Пример AbstractMap.SimpleEntry:
import java.util.Map;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
Instantiate:
ArrayList<Map.Entry<Integer, Integer>> arr =
new ArrayList<Map.Entry<Integer, Integer>>();
Добавить строки:
arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));
Получить строки:
System.out.println(arr.get(0).getKey());
System.out.println(arr.get(0).getValue());
System.out.println(arr.get(1).getKey());
System.out.println(arr.get(1).getValue());
System.out.println(arr.get(2).getKey());
System.out.println(arr.get(2).getValue());
Если печать:
2
3
20
30
2
4
Хорошо для определения ребер структур графа. Как между нейронами в вашей голове.
Ответ 5
Начиная с Java 9, появился новый служебный метод, позволяющий создавать неизменяемую запись, которая является Map#entry(Object, Object)
.
Вот простой пример:
Entry<String, String> entry = Map.entry("foo", "bar");
Поскольку он неизменен, вызов setValue
вызовет setValue
UnsupportedOperationException
. Другие ограничения в том, что это не сериализации и null
в качестве ключа или значения запрещено, если это не приемлемо для вас, вам нужно будет использовать AbstractMap.SimpleImmutableEntry
или AbstractMap.SimpleEntry
вместо этого.
NB. Если вам нужно напрямую создать Map
с парами от 0 до 10 (ключ, значение), вы можете вместо этого использовать методы типа Map.of(K key1, V value1,...)
.
Ответ 6
Почему Map.Entry
? Я думаю, что что-то вроде пары "ключ-значение" подходит для случая.
Используйте java.util.AbstractMap.SimpleImmutableEntry
или java.util.AbstractMap.SimpleEntry
Ответ 7
На самом деле вы могли бы пойти с: Map.Entry<String, String> en= Maps.immutableEntry(key, value);
Ответ 8
org.apache.commons.lang3.tuple.Pair
реализует java.util.Map.Entry
и может также использоваться автономно.
Также, как упоминалось ранее, Guava com.google.common.collect.Maps.immutableEntry(K, V)
выполняет трюк.
Я предпочитаю Pair
для его свободного Pair.of(L, R)
синтаксиса.
Ответ 9
Я определил общий класс Pair, который я использую все время. Это здорово. В качестве бонуса, определяя статический метод фабрики (Pair.create), мне нужно писать аргументы типа только вдвое реже.
public class Pair<A, B> {
private A component1;
private B component2;
public Pair() {
super();
}
public Pair(A component1, B component2) {
this.component1 = component1;
this.component2 = component2;
}
public A fst() {
return component1;
}
public void setComponent1(A component1) {
this.component1 = component1;
}
public B snd() {
return component2;
}
public void setComponent2(B component2) {
this.component2 = component2;
}
@Override
public String toString() {
return "<" + component1 + "," + component2 + ">";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((component1 == null) ? 0 : component1.hashCode());
result = prime * result
+ ((component2 == null) ? 0 : component2.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Pair<?, ?> other = (Pair<?, ?>) obj;
if (component1 == null) {
if (other.component1 != null)
return false;
} else if (!component1.equals(other.component1))
return false;
if (component2 == null) {
if (other.component2 != null)
return false;
} else if (!component2.equals(other.component2))
return false;
return true;
}
public static <A, B> Pair<A, B> create(A component1, B component2) {
return new Pair<A, B>(component1, component2);
}
}
Ответ 10
Если вы используете Clojure, у вас есть еще один вариант:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))