Java-如何创建新的条目(键,值)


291

我想创建一个类似于新项目Util.Map.Entry将包含结构keyvalue

问题是我无法实例化一个,Map.Entry因为它是一个接口。

有谁知道如何为Map.Entry创建新的通用键/值对象?

Answers:


79

您可以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());

117
当然-我只是想知道是否没有现成的解决方案。我正在尝试使我的代码尽可能标准...
Spiderman

1
您能否解释一下为什么Map的某些实现具有最终键(例如HashMap,ConcurrentHashMap中的键),而没有某些其他实现(例如TreeMap,WeakHashMap)中的键?
AKS

7
给定的代码不完全正确,因为它也不会覆盖equals和hashCode接口Map.Entry
John Tang Boyland

从Java 7 Update 80开始,我已经实现了以上功能,并且可以正常工作(pastebin)。没有其他方法可以被覆盖。

806

public static class AbstractMap.SimpleEntry<K,V>。不要让Abstract部分名称误导你:这其实不是一个abstract类(但其顶层AbstractMap是)。

这是一个事实static嵌套类意味着你不要需要一个封闭的AbstractMap情况下进行实例化,所以像这样的编译罚款:

Map.Entry<String,Integer> entry =
    new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);

如另一个答案所述,番石榴还提供了一种方便的static工厂方法供Maps.immutableEntry您使用。


你说:

我不能使用Map.Entry自身,因为它显然是一个只读对象,无法实例化newinstanceof

这并不完全正确。之所以不能直接实例化它(即使用new)的原因是因为它是一个interface Map.Entry


警告和提示

如文档中所述,AbstractMap.SimpleEntry@since 1.6,因此如果您坚持使用5.0,那么它将对您不可用。

要查找另一个已知的类,implements Map.Entry实际上您可以直接转到javadoc。从Java 6版本开始

接口映射条目

所有已知的实施类

不幸的是,1.5版未列出您可以使用的任何已知实现类,因此您可能会被困在实现自己的类中。


上一行为我返回了编译错误(我正在使用Java 5,BTW)-错误消息是:'类型AbstractMap.SimpleEntry不可见'
Spiderman 2010年

6
这是因为AbstractMap.SimpleEntry直到Java 6才公开。
Jesper 2010年

好的,因此总结一下简短的讨论-Java 5中没有针对它的现成解决方案-我应该对其使用自己的实现。
蜘蛛侠

4
+1指出AbstractMap.SimpleEntry。我想你每天都学到新东西!
Priidu Neemre

封闭在“封闭的AbstractMap实例”中是什么意思。封装是在Java中推论技术术语还是其他内容?请指导我。
C图形

70

Java 9开始有一个新的实用程序方法允许创建一个不可变条目Map#entry(Object, Object)

这是一个简单的示例:

Entry<String, String> entry = Map.entry("foo", "bar");

由于它是不可变的,因此调用setValue将抛出UnsupportedOperationException。其他限制是不可序列化的事实,并且null由于键或值被禁止,如果您不接受它,则需要使用AbstractMap.SimpleImmutableEntryAbstractMap.SimpleEntry代替。

注意:如果您需要直接创建Map包含0到10(键,值)对的a,则可以改用type方法Map.of(K key1, V value1, ...)



34

AbstractMap.SimpleEntry的示例:

import java.util.Map; 
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;

实例化:

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

定义图结构的边缘非常有用。就像大脑中神经元之间的神经元一样。


18

您实际上可以使用: Map.Entry<String, String> en= Maps.immutableEntry(key, value);


很有用 github.com/google/guava Guava是Google的一组核心Java库,其中包括新的集合类型(例如多图和多集),不可变的集合,图形库以及用于并发,I / O,哈希,缓存,原语,字符串等等!它广泛用于Google的大多数Java项目中,也被许多其他公司广泛使用。
Languoguang

13

为什么Map.Entry呢 我猜像键值对之类的东西适合这种情况。

使用java.util.AbstractMap.SimpleImmutableEntryjava.util.AbstractMap.SimpleEntry


6

org.apache.commons.lang3.tuple.Pair工具java.util.Map.Entry,也可以独立使用。

就像其他人提到的com.google.common.collect.Maps.immutableEntry(K, V)那样,番石榴也能达到目的。

我更喜欢Pair它流利的Pair.of(L, R)语法。


2
我可以建议ImmutablePair吗?
beluchin

我真的很喜欢org.apache.commons.lang3.tuple.Pair类,太棒了!
Laurens Op't Zandt'4

我唯一不喜欢的是它被序列化为left,right,key,value,其中left = key和right = value。序列化字符串中仅2个额外的无用(也许)值。
Vikrant Goel's

4

我定义了一个我一直使用的通用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);
    }

}

1
抱歉,我在阅读所有其他评论之前发布了此信息。看起来您想要标准库中包含的内容...
Nels Beckman 2010年

2
Google Guava很好地说明了为什么Pair实现是一件坏事。消息来源
IngoBürk,2014年

3

如果您正在使用Clojure,则还有另一种选择:

(defn map-entry
  [k v]
  (clojure.lang.MapEntry/create k v))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.