[英]Java - How to create new Entry (key, value)
I'd like to create new item that similarly to Util.Map.Entry
that will contain the structure key
, value
.我想创建类似于
Util.Map.Entry
新项目,它将包含结构key
, value
。
The problem is that I can't instantiate a Map.Entry
because it's an interface.问题是我无法实例化
Map.Entry
因为它是一个接口。
Does anyone know how to create a new generic key/value object for Map.Entry?有谁知道如何为 Map.Entry 创建一个新的通用键/值对象?
There's public static class AbstractMap.SimpleEntry<K,V>
.有
public static class AbstractMap.SimpleEntry<K,V>
。 Don't let the Abstract
part of the name mislead you: it is in fact NOT an abstract
class (but its top-level AbstractMap
is).不要让名称的
Abstract
部分误导您:它实际上不是一个abstract
类(但它的顶级AbstractMap
是)。
The fact that it's a static
nested class means that you DON'T need an enclosing AbstractMap
instance to instantiate it, so something like this compiles fine:这是一个事实
static
嵌套类意味着你不需要一个封闭AbstractMap
实例来实例化,所以像这样的编译罚款:
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
As noted in another answer, Guava also has a convenient static
factory method Maps.immutableEntry
that you can use.正如另一个答案中所述,Guava 还有一个方便的
static
工厂方法Maps.immutableEntry
您使用。
You said:你说:
I can't use
Map.Entry
itself because apparently it's a read-only object that I can't instantiate newinstanceof
我不能使用
Map.Entry
本身,因为显然它是一个只读对象,我无法实例化新的instanceof
That's not entirely accurate.这并不完全准确。 The reason why you can't instantiate it directly (ie with
new
) is because it's an interface Map.Entry
.不能直接(即使用
new
)实例化它的原因是因为它是一个interface Map.Entry
。
As noted in the documentation, AbstractMap.SimpleEntry
is @since 1.6
, so if you're stuck to 5.0, then it's not available to you.如文档中所述,
AbstractMap.SimpleEntry
是@since 1.6
,因此如果您坚持使用 5.0,那么您将无法使用它。
To look for another known class that implements Map.Entry
, you can in fact go directly to the javadoc.要查找另一个
implements Map.Entry
已知类,您实际上可以直接转到 javadoc。 From the Java 6 version从Java 6 版本开始
Interface Map.Entry
接口映射.Entry
All Known Implementing Classes :
所有已知的实现类:
Unfortunately the 1.5 version does not list any known implementing class that you can use, so you may have be stuck with implementing your own.不幸的是, 1.5 版本没有列出您可以使用的任何已知实现类,因此您可能一直在实现自己的类。
Starting from Java 9, there is a new utility method allowing to create an immutable entry which is Map#entry(Object, Object)
.从Java 9开始,有一个新的实用程序方法允许创建一个不可变的条目
Map#entry(Object, Object)
。
Here is a simple example:这是一个简单的例子:
Entry<String, String> entry = Map.entry("foo", "bar");
As it is immutable, calling setValue
will throw an UnsupportedOperationException
.由于它是不可变的,调用
setValue
将抛出UnsupportedOperationException
。 The other limitations are the fact that it is not serializable and null
as key or value is forbidden, if it is not acceptable for you, you will need to use AbstractMap.SimpleImmutableEntry
or AbstractMap.SimpleEntry
instead.其他限制是它不可序列化并且禁止作为键或值使用
null
,如果您不能接受,则需要使用AbstractMap.SimpleImmutableEntry
或AbstractMap.SimpleEntry
代替。
NB: If your need is to create directly a Map
with 0 to up to 10 (key, value) pairs, you can instead use the methods of type Map.of(K key1, V value1, ...)
.注意:如果您需要直接创建一个包含 0 到最多 10 个(键,值)对的
Map
,您可以改用Map.of(K key1, V value1, ...)
类型的方法。
You can just implement the Map.Entry<K, V>
interface yourself:你可以自己实现
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;
}
}
And then use it:然后使用它:
Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
Try Maps.immutableEntry from Guava尝试来自Guava 的Maps.immutableEntry
This has the advantage of being compatible with Java 5 (unlike AbstractMap.SimpleEntry
which requires Java 6.)这具有与 Java 5 兼容的优点(与需要 Java 6 的
AbstractMap.SimpleEntry
不同。)
Example of AbstractMap.SimpleEntry: 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>>();
Add rows:添加行:
arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));
Fetch rows:获取行:
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());
Should print:应该打印:
2
3
20
30
2
4
It's good for defining edges of graph structures.它适用于定义图结构的边。 Like the ones between neurons in your head.
就像大脑中神经元之间的那些。
您实际上可以使用: Map.Entry<String, String> en= Maps.immutableEntry(key, value);
Why Map.Entry
?为什么是
Map.Entry
? I guess something like a key-value pair is fit for the case.我想像键值对这样的东西适合这种情况。
Use java.util.AbstractMap.SimpleImmutableEntry
or java.util.AbstractMap.SimpleEntry
使用
java.util.AbstractMap.SimpleImmutableEntry
或java.util.AbstractMap.SimpleEntry
If you look at the documentation of Map.Entry you will find that it is a static interface (an interface which is defined inside the Map interface an can be accessed through Map.Entry) and it has two implementations如果您查看 Map.Entry 的文档,您会发现它是一个静态接口(在 Map 接口内部定义的接口,可以通过 Map.Entry 访问)并且它有两个实现
All Known Implementing Classes:
所有已知的实现类:
AbstractMap.SimpleEntry, AbstractMap.SimpleImmutableEntryAbstractMap.SimpleEntry, AbstractMap.SimpleImmutableEntry
The class AbstractMap.SimpleEntry provides 2 constructors: AbstractMap.SimpleEntry类提供了 2 个构造函数:
Constructors and Description
构造函数和描述
AbstractMap.SimpleEntry(K key, V value)AbstractMap.SimpleEntry(K 键,V 值)
Creates an entry representing a mapping from the specified key to the创建一个条目,表示从指定键到
specified value.指定值。
AbstractMap.SimpleEntry(Map.Entry<? extends K,? extends V> entry)AbstractMap.SimpleEntry(Map.Entry<? extends K,? extends V> entry)
Creates an entry representing the same mapping as the specified entry.创建一个条目,表示与指定条目相同的映射。
An example use case:一个示例用例:
import java.util.Map;
import java.util.AbstractMap.SimpleEntry;
public class MyClass {
public static void main(String args[]) {
Map.Entry e = new SimpleEntry<String, String>("Hello","World");
System.out.println(e.getKey()+" "+e.getValue());
}
}
org.apache.commons.lang3.tuple.Pair
implements java.util.Map.Entry
and can also be used standalone. org.apache.commons.lang3.tuple.Pair
实现了java.util.Map.Entry
,也可以独立使用。
Also as others mentioned Guava's com.google.common.collect.Maps.immutableEntry(K, V)
does the trick.正如其他人提到的,番石榴的
com.google.common.collect.Maps.immutableEntry(K, V)
可以解决问题。
I prefer Pair
for its fluent Pair.of(L, R)
syntax.我更喜欢
Pair
其流畅的Pair.of(L, R)
语法。
I defined a generic Pair class that I use all the time.我定义了一个我一直使用的通用 Pair 类。 It's great.
这很棒。 As a bonus, by defining a static factory method (Pair.create) I only have to write the type arguments half as often.
作为奖励,通过定义一个静态工厂方法 (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);
}
}
If you are using Clojure, you have another option:如果您使用的是 Clojure,您还有另一种选择:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.