Tôi muốn tạo một mục mới tương tự như vậy Util.Map.Entry
sẽ chứa cấu trúc key
, value
.
Vấn đề là tôi không thể khởi tạo một Map.Entry
vì nó là một giao diện.
Có ai biết cách tạo một đối tượng khóa / giá trị chung mới cho Map.Entry không?
Tôi muốn tạo một mục mới tương tự như vậy Util.Map.Entry
sẽ chứa cấu trúc key
, value
.
Vấn đề là tôi không thể khởi tạo một Map.Entry
vì nó là một giao diện.
Có ai biết cách tạo một đối tượng khóa / giá trị chung mới cho Map.Entry không?
Câu trả lời:
Bạn chỉ có thể tự thực hiện Map.Entry<K, V>
giao diện:
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;
}
}
Và sau đó sử dụng nó:
Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
Có public static class AbstractMap.SimpleEntry<K,V>
. Đừng để Abstract
phần tên đánh lừa bạn: thực tế nó KHÔNG phải là một abstract
lớp (nhưng cấp cao nhất của nó AbstractMap
là).
Thực tế rằng đó là một static
lớp lồng nhau có nghĩa là bạn KHÔNG cần một AbstractMap
cá thể kèm theo để khởi tạo nó, vì vậy một cái gì đó như thế này sẽ biên dịch tốt:
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
Như đã lưu ý trong một câu trả lời khác, Guava cũng có một static
phương pháp nhà máy thuận tiện Maps.immutableEntry
mà bạn có thể sử dụng.
Bạn đã nói:
Tôi không thể sử dụng
Map.Entry
chính nó vì rõ ràng đó là một đối tượng chỉ đọc mà tôi không thể khởi tạo mớiinstanceof
Điều đó không hoàn toàn chính xác. Lý do tại sao bạn không thể khởi tạo nó trực tiếp (tức là với new
) là vì đó là một interface Map.Entry
.
Như đã lưu ý trong tài liệu AbstractMap.SimpleEntry
này @since 1.6
, vì vậy, nếu bạn bị kẹt ở 5.0, thì nó không có sẵn cho bạn.
Để tìm một lớp đã biết khác implements Map.Entry
, trên thực tế bạn có thể truy cập trực tiếp vào javadoc. Từ phiên bản Java 6
Giao diện bản đồ.Entry
Tất cả các lớp triển khai đã biết :
Thật không may, phiên bản 1.5 không liệt kê bất kỳ lớp triển khai đã biết nào mà bạn có thể sử dụng, do đó bạn có thể bị mắc kẹt với việc triển khai của riêng bạn.
AbstractMap.SimpleEntry
không công khai cho đến Java 6, như bạn có thể thấy trong tài liệu.
AbstractMap.SimpleEntry
. Tôi đoán bạn học được một vài thứ mới mỗi ngày!
Bắt đầu từ Java 9, có một phương thức tiện ích mới cho phép tạo ra một mục bất biến Map#entry(Object, Object)
.
Đây là một ví dụ đơn giản:
Entry<String, String> entry = Map.entry("foo", "bar");
Như nó là bất biến, gọi setValue
sẽ ném một UnsupportedOperationException
. Những hạn chế khác là thực tế là nó không được tuần tự hóa và null
vì khóa hoặc giá trị bị cấm, nếu nó không được chấp nhận cho bạn, bạn sẽ cần phải sử dụng AbstractMap.SimpleImmutableEntry
hoặc AbstractMap.SimpleEntry
thay vào đó.
Lưu ý: Nếu nhu cầu của bạn là tạo trực tiếp a Map
với các cặp từ 0 đến tối đa 10 (khóa, giá trị), thay vào đó bạn có thể sử dụng các phương thức loại Map.of(K key1, V value1, ...)
.
Hãy dùng thử Maps.immutableEntry từ ổi
Điều này có lợi thế là tương thích với Java 5 (không giống như AbstractMap.SimpleEntry
yêu cầu Java 6.)
Ví dụ về AbstractMap.SimpleEntry:
import java.util.Map;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
Khởi tạo:
ArrayList<Map.Entry<Integer, Integer>> arr =
new ArrayList<Map.Entry<Integer, Integer>>();
Thêm hàng:
arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));
Lấy các hàng:
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());
Nên in:
2
3
20
30
2
4
Nó tốt cho việc xác định các cạnh của cấu trúc đồ thị. Giống như những người giữa các tế bào thần kinh trong đầu của bạn.
Bạn thực sự có thể đi với:
Map.Entry<String, String> en= Maps.immutableEntry(key, value);
org.apache.commons.lang3.tuple.Pair
thực hiện java.util.Map.Entry
và cũng có thể được sử dụng độc lập.
Cũng như những người khác đã đề cập đến Guava com.google.common.collect.Maps.immutableEntry(K, V)
.
Tôi thích cú pháp Pair
trôi chảy của nó Pair.of(L, R)
.
ImmutablePair
thay thế?
Tôi đã định nghĩa một lớp Pair chung mà tôi sử dụng mọi lúc. Thật tuyệt vời. Như một phần thưởng, bằng cách xác định một phương thức nhà máy tĩnh (Pair.create), tôi chỉ phải viết các đối số kiểu một nửa thường xuyên.
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);
}
}
Nếu bạn đang sử dụng Clojure, bạn có một tùy chọn khác:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))