tipos - Java-Cómo crear una nueva entrada(clave, valor)
pasos para crear un componente en java (10)
¿Por qué Map.Entry
? Supongo que algo como un par clave-valor es adecuado para el caso.
Utilice java.util.AbstractMap.SimpleImmutableEntry
o java.util.AbstractMap.SimpleEntry
Me gustaría crear un nuevo elemento similar al de Util.Map.Entry
que contendrá la key
estructura, value
.
El problema es que no puedo crear una instancia de Map.Entry
porque es una interfaz.
¿Alguien sabe cómo crear un nuevo objeto genérico de clave / valor para Map.Entry?
A partir de Java 9, hay un nuevo método de utilidad que permite crear una entrada inmutable que es la Map#entry(Object, Object)
.
Aquí hay un ejemplo simple:
Entry<String, String> entry = Map.entry("foo", "bar");
Como es inmutable, llamar a setValue
lanzará una setValue
UnsupportedOperationException
. Las otras limitaciones son el hecho de que no es serializable y null
ya que la clave o el valor están prohibidos; si no es aceptable para usted, deberá usar AbstractMap.SimpleImmutableEntry
o AbstractMap.SimpleEntry
Definí una clase de par genérico que uso todo el tiempo. Es genial. Como beneficio adicional, al definir un método de fábrica estático (Pair.create) solo tengo que escribir los argumentos de tipo con la misma frecuencia.
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);
}
}
En realidad, podría ir con: Map.Entry<String, String> en= Maps.immutableEntry(key, value);
Hay public static class AbstractMap.SimpleEntry<K,V>
. No deje que la parte Abstract
del nombre lo confunda: de hecho, NO es una clase abstract
(pero su AbstractMap
nivel superior es).
El hecho de que sea una clase anidada static
significa que NO necesita una instancia de AbstractMap
adjunta para instanciarla, por lo que algo como esto se compila bien:
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
Como se señaló en otra respuesta, Guava también tiene un método de fábrica static
conveniente Maps.immutableEntry
que puede usar.
Tu dijiste:
No puedo usar
Map.Entry
porque aparentemente es un objeto de solo lectura que no puedo crear una instancia de nuevainstanceof
Eso no es del todo exacto. La razón por la que no puede crear una instancia directamente (es decir, con una new
) es porque es una interface Map.Entry
.
Advertencia y propina
Como se indica en la documentación, AbstractMap.SimpleEntry
es @since 1.6
, por lo que si está atascado en 5.0, entonces no está disponible para usted.
Para buscar otra clase conocida que implements Map.Entry
, puede ir directamente al javadoc. De la versión de Java 6.
Mapa de interfaz. Ingreso
Todas las clases de implementación conocidas :
Desafortunadamente, la versión 1.5 no enumera ninguna clase de implementación conocida que pueda usar, por lo que es posible que se quede estancado con la implementación de la propia.
Prueba Maps.immutableEntry de Maps.immutableEntry
Esto tiene la ventaja de ser compatible con Java 5 (a diferencia de AbstractMap.SimpleEntry
que requiere Java 6).
Puede implementar la Map.Entry<K, V>
usted mismo:
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;
}
}
Y luego usarlo:
Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
Si está utilizando Clojure, tiene otra opción:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))
org.apache.commons.lang3.tuple.Pair
implementa java.util.Map.Entry
y también se puede usar de forma independiente.
También, como otros mencionaron, com.google.common.collect.Maps.immutableEntry(K, V)
Guava hace el truco.
Prefiero el Pair
por su Pair.of(L, R)
fluida Pair.of(L, R)
.
Ejemplo de AbstractMap.SimpleEntry:
import java.util.Map;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
Instanciar
ArrayList<Map.Entry<Integer, Integer>> arr =
new ArrayList<Map.Entry<Integer, Integer>>();
Añadir filas:
arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));
Fetch filas:
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());
Debería imprimir:
2
3
20
30
2
4
Es bueno para definir bordes de estructuras gráficas. Como las que hay entre las neuronas en tu cabeza.