정적지도를 초기화해야합니까?
Map
Java 에서 정적 을 어떻게 초기화하십니까?
방법 1 : 정적 이니셜 라이저
방법 2 : 인스턴스 이니셜 라이저 (익명 서브 클래스) 또는 다른 방법?
각각의 장단점은 무엇입니까?
다음은 두 가지 방법을 예입니다.
import java.util.HashMap;
import java.util.Map;
public class Test {
private static final Map<Integer, String> myMap = new HashMap<Integer, String>();
static {
myMap.put(1, "one");
myMap.put(2, "two");
}
private static final Map<Integer, String> myMap2 = new HashMap<Integer, String>(){
{
put(1, "one");
put(2, "two");
}
};
}
이 경우 인스턴스 이니셜 라이저는 단지 구문 적 설탕입니다. 맞죠? 초기화하기 위해 추가 익명 클래스가 필요한 이유를 모르겠습니다. 그리고 생성되는 클래스가 최종이면 작동하지 않습니다.
정적 이니셜 라이저를 사용하여 불변지도를 만들 수도 있습니다.
public class Test {
private static final Map<Integer, String> myMap;
static {
Map<Integer, String> aMap = ....;
aMap.put(1, "one");
aMap.put(2, "two");
myMap = Collections.unmodifiableMap(aMap);
}
}
나는 정적 인 불변의 맵을 초기화 하는 Guava 방식을 좋아합니다 .
static final Map<Integer, String> MY_MAP = ImmutableMap.of(
1, "one",
2, "two"
);
보시다시피 매우 간결합니다 (의 편리한 공장 방법 때문에 ).ImmutableMap
지도에 5 개 이상의 항목이 더 이상 사용할 수 없습니다 ImmutableMap.of()
. 대신 다음 줄을 따라 시도하십시오 .ImmutableMap.builder()
static final Map<Integer, String> MY_MAP = ImmutableMap.<Integer, String>builder()
.put(1, "one")
.put(2, "two")
// ...
.put(15, "fifteen")
.build();
Guava 사용 설명서에 설명 된 변경 불가능한 수집 항목을 참조하십시오 .
(의 일부) Guava는 Google 컬렉션 이라고 불렀습니다 . 아직 Java 프로젝트 에서이 라이브러리를 사용하고 있지면 보는 것이 좋습니다 ! Guava는 동료 SO 사용자가 동의하는 대로 Java 용으로 가장 인기있는 유용한 기능 라이브러리 하나가 . (당신이 사용하는 익숙하지 않다면, 그 링크 훌륭한 학습 자원이 있습니다.)
업데이트 (2015) : Java 8의 경우 다른 것보다 훨씬 깨끗하기 때문에 여전히 Guava 접근 방식을 사용합니다. 구아바을 원하지 않는 종속성 경우 또는 일반 오래된 초기화를 메서드 고려하십시오 . 2 차원 배열 및 스트림 API를 사용 하여 해킹 은 저에게 물어 보면 매우 추하고 키와이 동일한 유형이 아닌 맵을 매개 변수 할 경우 (질문에서와 같이) 추악 해 처리 Map<Integer, String>
합니다.
자바 팔에 일반적으로 구아바의 미래에 소개는, 루이 Wasserman 은이 말했다 2014 년 다시하고 [ 현재 발표 된 구아바 (21)가 발표 한 구아바 (8)가 필요합니다 .
Update (2016) :로 Tagir Valeev 보낸 지적 , 자바 (9) 마지막으로 추가하여, 아무것도하지만, 순수한 JDK를 사용하지 않고 할이없는 편의 팩토리 메소드 모음을 :
static final Map<Integer, String> MY_MAP = Map.of(
1, "one",
2, "two"
);
다음을 사용합니다.
public class Test {
private static final Map<Integer, String> MY_MAP = createMap();
private static Map<Integer, String> createMap() {
Map<Integer, String> result = new HashMap<Integer, String>();
result.put(1, "one");
result.put(2, "two");
return Collections.unmodifiableMap(result);
}
}
- 개인적으로 나쁜 스타일이라고 생각하는 익명의 클래스를 피하고
- 맵 생성을보다 명확하게합니다.
- 지도를 만들 수 없습니다.
- MY_MAP은 상수로 상수처럼 이름을 지정합니다.
Java 5는보다 간결한 구문을 제공합니다.
static final Map<String , String> FLAVORS = new HashMap<String , String>() {{
put("Up", "Down");
put("Charm", "Strange");
put("Top", "Bottom");
}};
두 번째 방법의 한 가지 장점 Collections.unmodifiableMap()
은 나중에 컬렉션을 업데이트하지 않도록 합니다.
private static final Map<Integer, String> CONSTANT_MAP =
Collections.unmodifiableMap(new HashMap<Integer, String>() {{
put(1, "one");
put(2, "two");
}});
// later on...
CONSTANT_MAP.put(3, "three"); // going to throw an exception!
다음은 Java 8 단선 정적지도 이니셜 라이저입니다.
private static final Map<String, String> EXTENSION_TO_MIMETYPE =
Arrays.stream(new String[][] {
{ "txt", "text/plain" },
{ "html", "text/html" },
{ "js", "application/javascript" },
{ "css", "text/css" },
{ "xml", "application/xml" },
{ "png", "image/png" },
{ "gif", "image/gif" },
{ "jpg", "image/jpeg" },
{ "jpeg", "image/jpeg" },
{ "svg", "image/svg+xml" },
}).collect(Collectors.toMap(kv -> kv[0], kv -> kv[1]));
편집 : Map<Integer, String>
질문에서와 같이 초기화 하려면 다음과 같은 것이 필요합니다.
static final Map<Integer, String> MY_MAP = Arrays.stream(new Object[][]{
{1, "one"},
{2, "two"},
}).collect(Collectors.toMap(kv -> (Integer) kv[0], kv -> (String) kv[1]));
Edit (2) : new SimpleEntry<>(k, v)
호출 스트림을 사용하는 i_am_zero의 더 나은 혼합 유형 지원 버전이 있습니다. 그 대답을 확인하십시오 : https://stackoverflow.com/a/37384773/3950982
자바 9에서
private static final Map<Integer, String> MY_MAP = Map.of(1, "one", 2, "two");
자세한 내용은 JEP 269 를 참조하십시오. JDK 9는 2017 년 9 월에 정식 출시 되었습니다.
자바 9
우리는 다음 Map.ofEntries
과 같이 사용할 수 있습니다 .
import static java.util.Map.entry;
private static final Map<Integer,String> map = Map.ofEntries(
entry(1, "one"),
entry(2, "two"),
entry(3, "three"),
entry(4, "four"),
entry(5, "five"),
entry(6, "six"),
entry(7, "seven"),
entry(8, "eight"),
entry(9, "nine"),
entry(10, "ten"));
여기Map.of
에 Tagir의 답변에서 제안한대로 사용할 수도 있습니다 .Map.of
Java 8 (Neat 솔루션)
맵 항목 스트림을 만들 수 있습니다. 는 이미 두 우리 가지 구현이 Entry
에 java.util.AbstractMap
있는 있습니다 SimpleEntry 및 SimpleImmutableEntry을 . 이 예에서는 전자를 다음과 같이 사용할 수 있습니다.
import java.util.AbstractMap.*;
private static final Map<Integer, String> myMap = Stream.of(
new SimpleEntry<>(1, "one"),
new SimpleEntry<>(2, "two"),
new SimpleEntry<>(3, "three"),
new SimpleEntry<>(4, "four"),
new SimpleEntry<>(5, "five"),
new SimpleEntry<>(6, "six"),
new SimpleEntry<>(7, "seven"),
new SimpleEntry<>(8, "eight"),
new SimpleEntry<>(9, "nine"),
new SimpleEntry<>(10, "ten"))
.collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue));
함께 이클립스 컬렉션 , 다음의 모든 작동합니다 :
import java.util.Map;
import org.eclipse.collections.api.map.ImmutableMap;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.impl.factory.Maps;
public class StaticMapsTest
{
private static final Map<Integer, String> MAP =
Maps.mutable.with(1, "one", 2, "two");
private static final MutableMap<Integer, String> MUTABLE_MAP =
Maps.mutable.with(1, "one", 2, "two");
private static final MutableMap<Integer, String> UNMODIFIABLE_MAP =
Maps.mutable.with(1, "one", 2, "two").asUnmodifiable();
private static final MutableMap<Integer, String> SYNCHRONIZED_MAP =
Maps.mutable.with(1, "one", 2, "two").asSynchronized();
private static final ImmutableMap<Integer, String> IMMUTABLE_MAP =
Maps.mutable.with(1, "one", 2, "two").toImmutable();
private static final ImmutableMap<Integer, String> IMMUTABLE_MAP2 =
Maps.immutable.with(1, "one", 2, "two");
}
Eclipse 컬렉션을 사용하여 기본 맵을 정적으로 초기화 할 수도 있습니다.
import org.eclipse.collections.api.map.primitive.ImmutableIntObjectMap;
import org.eclipse.collections.api.map.primitive.MutableIntObjectMap;
import org.eclipse.collections.impl.factory.primitive.IntObjectMaps;
public class StaticPrimitiveMapsTest
{
private static final MutableIntObjectMap<String> MUTABLE_INT_OBJ_MAP =
IntObjectMaps.mutable.<String>empty()
.withKeyValue(1, "one")
.withKeyValue(2, "two");
private static final MutableIntObjectMap<String> UNMODIFIABLE_INT_OBJ_MAP =
IntObjectMaps.mutable.<String>empty()
.withKeyValue(1, "one")
.withKeyValue(2, "two")
.asUnmodifiable();
private static final MutableIntObjectMap<String> SYNCHRONIZED_INT_OBJ_MAP =
IntObjectMaps.mutable.<String>empty()
.withKeyValue(1, "one")
.withKeyValue(2, "two")
.asSynchronized();
private static final ImmutableIntObjectMap<String> IMMUTABLE_INT_OBJ_MAP =
IntObjectMaps.mutable.<String>empty()
.withKeyValue(1, "one")
.withKeyValue(2, "two")
.toImmutable();
private static final ImmutableIntObjectMap<String> IMMUTABLE_INT_OBJ_MAP2 =
IntObjectMaps.immutable.<String>empty()
.newWithKeyValue(1, "one")
.newWithKeyValue(2, "two");
}
참고 : 저는 Eclipse 컬렉션의 커미터입니다.
이 상황에서는 익명의 하위 클래스를 만들지 언어로 작성합니다. 예를 들어 생성 된 맵을 수 완성해서 생성 한 정적 이니셜 라이가 똑같이 잘 작동합니다.
private static final Map<Integer, String> MY_MAP;
static
{
Map<Integer, String>tempMap = new HashMap<Integer, String>();
tempMap.put(1, "one");
tempMap.put(2, "two");
MY_MAP = Collections.unmodifiableMap(tempMap);
}
페이지에있는 동영상과 같은 Google 컬렉션 을 확인하는 것이 흥미로울 수 있습니다 . 맵과 세트를 초기화하는 다양한 방법을 제공하고 변경이 불가능한 컬렉션도 제공합니다.
업데이트 :이 라이브러리의 이름은 이제 Guava 입니다.
처리하기 쉽기 때문에 익명 클래스를 좋아합니다.
public static final Map<?, ?> numbers = Collections.unmodifiableMap(new HashMap<Integer, String>() {
{
put(1, "some value");
//rest of code here
}
});
public class Test {
private static final Map<Integer, String> myMap;
static {
Map<Integer, String> aMap = ....;
aMap.put(1, "one");
aMap.put(2, "two");
myMap = Collections.unmodifiableMap(aMap);
}
}
둘 이상의 상수를 선언하면 해당 코드는 정적 블록으로 작성되고 유지 관리가 어렵습니다. 따라서 익명 클래스를 사용하는 것이 좋습니다.
public class Test {
public static final Map numbers = Collections.unmodifiableMap(new HashMap(2, 1.0f){
{
put(1, "one");
put(2, "two");
}
});
}
그리고 상수로 unmodifiableMap을 사용하는 것이 좋습니다. 구분 상수로 취급 할 수 없습니다.
정적 블록 스타일보다 "이중 중괄호 초기화"스타일을 강력하게 제안 할 수 있습니다.
누군가는 익명의 클래스, 오버 헤드, 성능 등을 좋아하지 않는다고 말할 수 있습니다.
그러나 내가 더 고려하는 것은 코드 가독성과 유지 보수성입니다. 이 관점에서 이중 중괄호는 정적 메서드보다 더 나은 코드 스타일입니다.
- 요소는 중첩되고 인라인됩니다.
- 절차가 아닌 OO에 가깝습니다.
- 성능에 효율적으로 사용할 수 있습니다.
- 더 나은 IDE 개요 지원 (많은 익명 정적 {} 블록이 아님)
- 관계를 맺기 위해 몇 줄의 주석을 저장했습니다.
- 예외 및 바이트 코드 최적화 프로그램에서 초기화되지 않은 개체의 가능한 요소 / 인스턴스 리드를 방지합니다.
- 정적 블록의 실행 순서에 대해 걱정할 필요가 없습니다.
또한 익명 클래스의 GC를 알고 있으면 .NET을 사용하여 항상 일반 HashMap으로 변환 할 수 있습니다 new HashMap(Map map)
.
다른 문제에 직면 할 때까지 할 수 있습니다. 그렇게한다면 완전한 다른 코딩 스타일 (예 : 정적, 팩토리 클래스 없음)을 많이 사용합니다.
apache-commons에는 메소드와 같이 메소드 MapUtils.putAll (Map, Object [])이 있습니다 .
예를 들어, 색상 맵을 만들려면 :
Map<String, String> colorMap = MapUtils.putAll(new HashMap<String, String>(), new String[][] {
{"RED", "#FF0000"},
{"GREEN", "#00FF00"},
{"BLUE", "#0000FF"}
});
Guava의 사용을 사용할 경우 사용 가능한 ImmutableMap.of()
변경 항목이 필요한 경우 다음을 가장 좋아합니다 Map
.
public static <A> Map<String, A> asMap(Object... keysAndValues) {
return new LinkedHashMap<String, A>() {{
for (int i = 0; i < keysAndValues.length - 1; i++) {
put(keysAndValues[i].toString(), (A) keysAndValues[++i]);
}
}};
}
이것은 매우 간결하며 잘못된 값 (즉, 값이없는 최종 키)을 무시합니다.
용법 :
Map<String, String> one = asMap("1stKey", "1stVal", "2ndKey", "2ndVal");
Map<String, Object> two = asMap("1stKey", Boolean.TRUE, "2ndKey", new Integer(2));
Java 9 of
가 Map
인터페이스에 멋진 팩토리 메소드 를 추가했습니다 . 설정, 목록에도 추가 방법이 추가됩니다.
Map<String, String> unmodifiableMap = Map.of("key1", "value1", "key2", "value2");
익명 클래스 생성을 피하기 위해 정적 이니셜 라이저를 사용하는 것을 선호하는 것이 더 이상 목적이없는 정적 이니셜 라이저로 초기화하는 팁을하겠습니다. 모든 솔루션 / 팁은 형식이 안전합니다.
참고 : 이 질문은지도를 만들 수 있지만 아무 말도하지 않습니다 Collections.unmodifiableMap(map)
.
첫 번째 팁
첫 번째 팁은지도에 대한 로컬 참조를 만들고 짧은 이름을 로컬 참조 것입니다.
private static final Map<Integer, String> myMap = new HashMap<>();
static {
final Map<Integer, String> m = myMap; // Use short name!
m.put(1, "one"); // Here referencing the local variable which is also faster!
m.put(2, "two");
m.put(3, "three");
}
두 번째 팁
두 번째 팁은 항목을 추가하는 방법으로 만들 수있을 것입니다. 다음과 같은 경우에 도우미 메서드를 공개 할 수 있습니다.
private static final Map<Integer, String> myMap2 = new HashMap<>();
static {
p(1, "one"); // Calling the helper method.
p(2, "two");
p(3, "three");
}
private static void p(Integer k, String v) {
myMap2.put(k, v);
}
여기서 도우미 메서드는 .NET Framework 요소를 추가 할 수 있기 때문에 추가 할 수 없습니다 myMap2
. 초기화 할 수 있도록하기위한지도 자체를 도우미 초기화 코드는 더 짧지 만들 수 있습니다.
세 번째 팁
세 번째 팁은 채우기 기능을 사용하여 가능한 빌더와 같은 도우미 클래스를 만들 수있는 것입니다. 이 형식이 안전한 정말 간단한 10 줄 도우미 클래스입니다.
public class Test {
private static final Map<Integer, String> myMap3 = new HashMap<>();
static {
new B<>(myMap3) // Instantiating the helper class with our map
.p(1, "one")
.p(2, "two")
.p(3, "three");
}
}
class B<K, V> {
private final Map<K, V> m;
public B(Map<K, V> m) {
this.m = m;
}
public B<K, V> p(K k, V v) {
m.put(k, v);
return this; // Return this for chaining
}
}
생성중인 익명 클래스가 잘 작동합니다. 다음은 내부 클래스 내부 클래스 인스턴스에 대한 참조를 포함합니다. 따라서 XStream 을 사용하여 특정 작업을 수행 할 수 있습니다. 매우 이상한 오류가 발생합니다.
당신이 알고있는 한이 있어은 괜찮습니다. 나는 간결한 방식으로 모든 종류의 컬렉션을 초기화하기 위해 대부분의 시간을 사용합니다.
편집 : 정적 정적 클래스라는 주석에서 지적했습니다. 나는 분명히 충분히 자세히 읽었습니다. 그러나 내 의견 은 여전히 익명의 내부 클래스에 적용됩니다.
간결하고 실용적인 것을 보여줍니다. 타임 유형 검사를 실행으로 전환 할 수 있습니다.
static final Map<String, Integer> map = MapUtils.unmodifiableMap(
String.class, Integer.class,
"cat", 4,
"dog", 2,
"frog", 17
);
이 구현은 모든 오류를 발생시켜야합니다.
import java.util.HashMap;
public abstract class MapUtils
{
private MapUtils() { }
public static <K, V> HashMap<K, V> unmodifiableMap(
Class<? extends K> keyClazz,
Class<? extends V> valClazz,
Object...keyValues)
{
return Collections.<K, V>unmodifiableMap(makeMap(
keyClazz,
valClazz,
keyValues));
}
public static <K, V> HashMap<K, V> makeMap(
Class<? extends K> keyClazz,
Class<? extends V> valClazz,
Object...keyValues)
{
if (keyValues.length % 2 != 0)
{
throw new IllegalArgumentException(
"'keyValues' was formatted incorrectly! "
+ "(Expected an even length, but found '" + keyValues.length + "')");
}
HashMap<K, V> result = new HashMap<K, V>(keyValues.length / 2);
for (int i = 0; i < keyValues.length;)
{
K key = cast(keyClazz, keyValues[i], i);
++i;
V val = cast(valClazz, keyValues[i], i);
++i;
result.put(key, val);
}
return result;
}
private static <T> T cast(Class<? extends T> clazz, Object object, int i)
{
try
{
return clazz.cast(object);
}
catch (ClassCastException e)
{
String objectName = (i % 2 == 0) ? "Key" : "Value";
String format = "%s at index %d ('%s') wasn't assignable to type '%s'";
throw new IllegalArgumentException(String.format(format, objectName, i, object.toString(), clazz.getSimpleName()), e);
}
}
}
Java 8에서는 다음 패턴을 사용하게됩니다.
private static final Map<String, Integer> MAP = Stream.of(
new AbstractMap.SimpleImmutableEntry<>("key1", 1),
new AbstractMap.SimpleImmutableEntry<>("key2", 2)
).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
가장 간결하고 약간의 원형은
- 외부에서 아무것도 필요하지 않습니다.
java.util
- 유형이 안전하고 키와 값에 대해 다양한 유형을 쉽게 수용 할 수 있습니다.
은 사용할 수 당신 있습니다 과 에서 Cactoos :StickyMap
MapEntry
private static final Map<String, String> MAP = new StickyMap<>(
new MapEntry<>("name", "Jeffrey"),
new MapEntry<>("age", "35")
);
나는 정적 이니셜 라이저 구문을 좋아하지 않고 익명의 서브 클래스에 확신이 없습니다. 일반적으로 정적 정적 이니셜 라이저를 사용하는 모든 단점과 이전 사용에서 한 익명 하위 클래스를 사용하는 모든 단점에 동의합니다. 반면에 충분에 제시된 전문가는 저에게 충분하지 않습니다. 정적 초기화 방법을 사용하는 것을 선호합니다.
public class MyClass {
private static final Map<Integer, String> myMap = prepareMap();
private static Map<Integer, String> prepareMap() {
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "one");
hashMap.put(2, "two");
return hashMap;
}
}
나는 내가 사용하는 (그리고 좋아하게 된) 접근 방식을 어떤 답변에도 게시하지 않고 여기에 있습니다.
나는 정적 이니셜 라이저가 투박하기 때문에 사용하는 것을 좋아하지, 각 인스턴스에 대해 새 클래스를 생성하기 때문에 익명 클래스를 좋아하지 않습니다.
대신 다음과 같은 초기화를 선호합니다.
map(
entry("keyA", "val1"),
entry("keyB", "val2"),
entry("keyC", "val3")
);
안타깝게도 메소드는 표준 Java 라이브러리의 일부가 아니 메소드 다음 메소드를 정의하는 유틸리티 라이브러리를 작성 (또는 사용)해야합니다.
public static <K,V> Map<K,V> map(Map.Entry<K, ? extends V>... entries)
public static <K,V> Map.Entry<K,V> entry(K key, V val)
( '정적 가져 오기'를 사용하면 메소드 이름을 접두사로 필요가 없습니다)
다른 컬렉션 (list, set, sortedSet, sortedMap 등)에 대해 제안하는 방법을 제공하는 것이 유용하다는 것을 알았습니다.
json 초기화 초기화만큼 좋지는 않지만 가독성에 관한 한 그 방향으로 나아가는 단계입니다.
Java는 맵 리터럴을 지원하지 않기 때문에 맵 인스턴스는 항상 명시 적으로 인스턴스화되고 있어야합니다.
여러 가지 팩토리 메소드를 사용하여 Java에서 맵 리터럴의 동작을 근사화 할 수 있습니다 .
예를 들면 :
public class LiteralMapFactory {
// Creates a map from a list of entries
@SafeVarargs
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
LinkedHashMap<K, V> map = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
// Creates a map entry
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
public static void main(String[] args) {
System.out.println(mapOf(entry("a", 1), entry("b", 2), entry("c", 3)));
}
}
다수 :
{a = 1, b = 2, c = 3}
한 번에 한 요소 씩 맵을 만들고 채우는 것보다 훨씬 편리합니다.
맵에 하나의 값만 추가해야하는 경우 Collections.singletonMap 을 사용할 수 있습니다 .
Map<K, V> map = Collections.singletonMap(key, value)
두 번째 접근 방식 (Double Brace 초기화 ) 은 안티 패턴으로 생각 합니다. 첫 번째 접근 방식을 사용합니다.
정적 맵을 초기화하는 또 다른 쉬운 방법은 다음 유틸리티 함수를 사용하는 것입니다.
public static <K, V> Map<K, V> mapOf(Object... keyValues) {
Map<K, V> map = new HashMap<>(keyValues.length / 2);
for (int index = 0; index < keyValues.length / 2; index++) {
map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
}
return map;
}
Map<Integer, String> map1 = mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = mapOf("key1", "value1", "key2", "value2");
참고 : Map.ofJava 9
를 사용할 수 있습니다 .
JEP 269 는 Collections API에 대한 몇 가지 편리한 팩토리 메소드를 제공합니다. 이 팩토리 메소드는 현재 Java 버전 (8)이 있습니다 Java 9 릴리스에 계획되어 있습니다.
를 들어이 Map
두 공장 방법은 다음과 것 of
및 ofEntries
. 를 사용하면 of
교대로 키 / 값 쌍을 사용할 수 있습니다. 예를 들어, 다음 Map
과 같이 만들려면 {age: 27, major: cs}
다음을 수행하십시오.
Map<String, Object> info = Map.of("age", 27, "major", "cs");
현재에는 10 개의 오버로드 된 버전이 of
있으므로 10 개의 키 / 값 쌍을 포함하는지도를 만들 수 있습니다. 이 제한 또는 대체 키 / 값이 마음에 들지에서 사용할 수 있습니다 ofEntries
.
Map<String, Object> info = Map.ofEntries(
Map.entry("age", 27),
Map.entry("major", "cs")
);
of
그리고 둘 다 ofEntries
불변을 사용 Map
하여 생성 후 요소를 사용하지 않습니다. JDK 9 Early Access를 사용하여 기능을 볼 수 있습니다 .
글쎄 ... 나는 열거 형을 좋아한다;)
enum MyEnum {
ONE (1, "one"),
TWO (2, "two"),
THREE (3, "three");
int value;
String name;
MyEnum(int value, String name) {
this.value = value;
this.name = name;
}
static final Map<Integer, String> MAP = Stream.of( values() )
.collect( Collectors.toMap( e -> e.value, e -> e.name ) );
}
나는 답을 읽었습니다 나만의 맵 빌더를 쓰기로 결정했습니다. 자유롭게 복사하여 넣으십시오.
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A tool for easy creation of a map. Code example:<br/>
* {@code MapBuilder.of("name", "Forrest").and("surname", "Gump").build()}
* @param <K> key type (inferred by constructor)
* @param <V> value type (inferred by constructor)
* @author Vlasec (for http://stackoverflow.com/a/30345279/1977151)
*/
public class MapBuilder <K, V> {
private Map<K, V> map = new HashMap<>();
/** Constructor that also enters the first entry. */
private MapBuilder(K key, V value) {
and(key, value);
}
/** Factory method that creates the builder and enters the first entry. */
public static <A, B> MapBuilder<A, B> mapOf(A key, B value) {
return new MapBuilder<>(key, value);
}
/** Puts the key-value pair to the map and returns itself for method chaining */
public MapBuilder<K, V> and(K key, V value) {
map.put(key, value);
return this;
}
/**
* If no reference to builder is kept and both the key and value types are immutable,
* the resulting map is immutable.
* @return contents of MapBuilder as an unmodifiable map.
*/
public Map<K, V> build() {
return Collections.unmodifiableMap(map);
}
}
편집 : 최근에 나는 공개적인 메소드를 of
꽤 자주 찾고 조금 좋아합니다. 코드에 추가하고 생성 해 비공개로 설정하여 정적 팩토리 메서드 패턴으로 전환했습니다.
EDIT2 : 최근에는 of
정적 가져 오기를 오기를 사용할 때 상당히 나빠 보이기 때문에 정적 메소드를 더 좋아하지 않습니다 . mapOf
대신 이름을 변경하여 정적 가져 오기에 더 적합합니다.
참고 URL : https://stackoverflow.com/questions/507602/how-can-i-initialise-a-static-map
'ProgramingTip' 카테고리의 다른 글
Git에서 파일을 언 스테이징하는 두 가지 방법이있는 이유는 무엇입니까? (0) | 2020.09.27 |
---|---|
Python 클래스는 객체를 상속합니다. (0) | 2020.09.27 |
내 펼쳐를 실행중인 Python 버전을 어떻게 확인합니까? (0) | 2020.09.27 |
JavaScriptSerializer Serializer JSON- 열거 형을 쉽게 만들 수 있습니다. (0) | 2020.09.27 |
Ruby에서 키워드를 소문자 또는 대문자로 변환하는 방법 (0) | 2020.09.27 |