Java - How to create new Entry (key, value)

前端 未结 11 1509
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 09:55

I\'d like to create new item that similarly to Util.Map.Entry that will contain the structure key, value.

The problem is that

相关标签:
11条回答
  • 2020-11-27 09:59

    I defined a generic Pair class that I use all the time. 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.

    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);
        }
    
    }
    
    0 讨论(0)
  • 2020-11-27 10:01

    Example of 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.

    0 讨论(0)
  • 2020-11-27 10:02

    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

    All Known Implementing Classes:
    AbstractMap.SimpleEntry, AbstractMap.SimpleImmutableEntry

    The SimpleEntry class provides 2 constructors:

    Constructors
    SimpleEntry(K key, V value)
    Creates an entry representing a mapping from the specified key to the
    specified value. 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());
        }
    }
    
    0 讨论(0)
  • 2020-11-27 10:04

    Starting from Java 9, there is a new utility method allowing to create an immutable entry which is 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. 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.

    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 讨论(0)
  • 2020-11-27 10:12

    You can just implement the Map.Entry<K, V> interface yourself:

    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());
    
    0 讨论(0)
  • 2020-11-27 10:13

    There's 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).

    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:

    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.


    You said:

    I can't use Map.Entry itself because apparently it's a read-only object that I can't instantiate new instanceof

    That's not entirely accurate. The reason why you can't instantiate it directly (i.e. with new) is because it's an interface Map.Entry.


    Caveat and tip

    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.

    To look for another known class that implements Map.Entry, you can in fact go directly to the javadoc. From the Java 6 version

    Interface Map.Entry

    All Known Implementing Classes:

    • AbstractMap.SimpleEntry, AbstractMap.SimpleImmutableEntry

    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.

    0 讨论(0)
提交回复
热议问题