ฉันต้องการสร้างรายการใหม่ที่คล้ายกับUtil.Map.Entry
ที่จะมีโครงสร้างkey
, value
.
ปัญหาคือฉันไม่สามารถสร้างอินสแตนซ์ได้Map.Entry
เนื่องจากเป็นส่วนต่อประสาน
ไม่มีใครรู้วิธีสร้างวัตถุคีย์ / ค่าทั่วไปใหม่สำหรับ Map.Entry
ฉันต้องการสร้างรายการใหม่ที่คล้ายกับUtil.Map.Entry
ที่จะมีโครงสร้างkey
, value
.
ปัญหาคือฉันไม่สามารถสร้างอินสแตนซ์ได้Map.Entry
เนื่องจากเป็นส่วนต่อประสาน
ไม่มีใครรู้วิธีสร้างวัตถุคีย์ / ค่าทั่วไปใหม่สำหรับ Map.Entry
คำตอบ:
คุณสามารถใช้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());
public static class AbstractMap.SimpleEntry<K,V>
มี อย่าปล่อยให้Abstract
ส่วนหนึ่งของชื่อคุณเข้าใจผิด: มันเป็นในความเป็นจริงไม่abstract
ระดับ ( แต่ระดับบนสุดAbstractMap
คือ)
ความจริงที่ว่ามันเป็นstatic
คลาสที่ซ้อนกันหมายความว่าคุณไม่จำเป็นต้องมีAbstractMap
อินสแตนซ์ที่ล้อมรอบเพื่อยกตัวอย่างมันดังนั้นสิ่งที่คอมไพล์นี้รวบรวมได้:
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
ดังที่ได้กล่าวไว้ในคำตอบอื่น Guava ยังมีstatic
วิธีการใช้Maps.immutableEntry
ที่สะดวกจากโรงงานซึ่งคุณสามารถใช้ได้
คุณพูดว่า:
ฉันไม่สามารถใช้
Map.Entry
ตัวเองเพราะเห็นได้ชัดว่ามันเป็นวัตถุแบบอ่านอย่างเดียวที่ฉันไม่สามารถสร้างอินสแตนซ์ใหม่ได้instanceof
นั่นไม่ถูกต้องทั้งหมด เหตุผลที่คุณไม่สามารถยกตัวอย่างได้โดยตรง (คือมีnew
) interface Map.Entry
เป็นเพราะมันเป็น
ดังที่ระบุไว้ในเอกสารประกอบAbstractMap.SimpleEntry
คือ@since 1.6
หากคุณติดอยู่ที่ 5.0 แสดงว่าคุณไม่สามารถใช้งานได้
เพื่อมองหาอีกคลาสที่รู้จักกันดีว่า implements Map.Entry
ในความเป็นจริงคุณสามารถไปที่ javadoc โดยตรง จากเวอร์ชัน Java 6
อินเตอร์เฟส Map.Entry
คลาสการใช้งานที่รู้จักทั้งหมด :
น่าเสียดายที่รุ่น 1.5ไม่ได้ระบุคลาสการใช้งานที่รู้จักซึ่งคุณสามารถใช้ได้ดังนั้นคุณอาจติดอยู่กับการใช้งานของคุณเอง
AbstractMap.SimpleEntry
ยังไม่เปิดเผยจนกว่า Java 6 อย่างที่คุณเห็นในเอกสารประกอบ
AbstractMap.SimpleEntry
สำหรับการชี้ให้เห็น ฉันเดาว่าคุณเรียนรู้สิ่งใหม่ทุกวัน!
เริ่มต้นจากJava 9Map#entry(Object, Object)
มีวิธีที่อาคารใหม่ที่ช่วยให้การสร้างรายการที่ไม่เปลี่ยนรูปซึ่งเป็น
นี่คือตัวอย่างง่ายๆ:
Entry<String, String> entry = Map.entry("foo", "bar");
ในขณะที่มันจะไม่เปลี่ยนรูปโทรจะโยนsetValue
UnsupportedOperationException
ข้อ จำกัด อื่น ๆ นั้นเป็นข้อเท็จจริงที่ว่ามันไม่ได้เป็นแบบอนุกรมและnull
เป็นกุญแจสำคัญหรือค่าเป็นสิ่งต้องห้ามหากคุณไม่ได้รับการยอมรับคุณจะต้องใช้AbstractMap.SimpleImmutableEntry
หรือAbstractMap.SimpleEntry
แทน
หมายเหตุ:หากคุณต้องการสร้างคู่ที่Map
มี 0 ถึง 10 (คีย์, ค่า) โดยตรงคุณสามารถใช้วิธีการประเภทMap.of(K key1, V value1, ...)
แทน
ลองใช้Maps.immutableEntryจากGuava
สิ่งนี้มีข้อดีของการเข้ากันได้กับ Java 5 (ไม่เหมือนกับAbstractMap.SimpleEntry
Java 6)
ตัวอย่างของ 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
มันเป็นการดีสำหรับการกำหนดขอบของโครงสร้างกราฟ เหมือนเซลล์ประสาทในหัวของคุณ
คุณสามารถไปกับ:
Map.Entry<String, String> en= Maps.immutableEntry(key, value);
ทำไม Map.Entry
? ฉันเดาบางอย่างเช่นคู่คีย์ - ค่าเหมาะสำหรับเคส
ใช้java.util.AbstractMap.SimpleImmutableEntry
หรือjava.util.AbstractMap.SimpleEntry
org.apache.commons.lang3.tuple.Pair
ใช้java.util.Map.Entry
และสามารถใช้แบบสแตนด์อโลนได้
เช่นเดียวกับคนอื่น ๆ ที่กล่าวถึง Guava com.google.common.collect.Maps.immutableEntry(K, V)
ไม่หลอกลวง
ฉันชอบไวยากรณ์ที่Pair
คล่องแคล่วPair.of(L, R)
ImmutablePair
แทนได้ไหม
ฉันกำหนดคลาส 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);
}
}
Pair
การติดตั้งใช้งานจึงเป็นสิ่งที่ไม่ดี แหล่งที่มา
หากคุณกำลังใช้ Clojure คุณมีตัวเลือกอื่น:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))