Pytanie w sprawie collections, java – Jak używać literałów kolekcji w Javie 7?

19

Próbowałem następującej linii:

Map<Character, Color> map={new Character('r'):Color.red,new Character('b'):Color.black};

Jednak Netbeans 7 odrzuca to z komunikatem o błędzie'{' expected, ';' expected.

Ustawiłem format Source / Binary na „JDK 7”, a platformę na „JDK 1.7”. Czy muszę coś jeszcze zrobić?

W Javie 8 możesz użyć tego triku, aby uzyskać rozsądne literały map z wyrażeń lambda:gist.github.com/galdosd/10823529 Domingo Ignacio
Ta sztuczka zależy od używanego kompilatora. Myślę, że działa z Eclipse, ale nie z javac. Stuart Marks
Okrężnice wyglądają śmiesznie! :) user unknown

Twoja odpowiedź

3   odpowiedź
48

Ani Java 7, ani Java 8 nie obsługują literałów kolekcji, jak omówiono w tym pytaniu:Czy udoskonalenia kolekcji Project Coin będą dostępne w JDK8?

Możesz korzystać z GoogleGuawa biblioteka, jeśli potrzebujesz tylko niezmiennych kolekcji.ImmutableList, ImmutableSet iImmutableMap mają kilka przeciążonych metod fabrycznych lub nawet konstruktorów, które ułatwiają tworzenie kolekcji:

List<Integer> list = ImmutableList.of(1, 1, 2, 3, 5, 8, 13, 21);
Set<String> set = ImmutableSet.of("foo", "bar", "baz", "batman");
Map<Integer, String> map = ImmutableMap.of(1, "one", 2, "two", 3, "three");

EDYTOWAĆ

Dodano Java 9metody zakładania kolekcji podobne do tych z Guawy:

List.of(a, b, c);
Set.of(d, e, f, g);
Map.of(k1, v1, k2, v2)

Map.ofEntries(
    entry(k1, v1),
    entry(k2, v2),
    entry(k3, v3),
    // ...
    entry(kn, vn)
);
Och, powinienem to sprawdzić. Szkoda, naprawdę; Nie mogłem się doczekać użycia literałów kolekcji. Dzięki! DaedalusUsedPerl
11

Musisz zdefiniować konkretną implementację mapy, opcjonalnie połączoną z inicjalizacją podwójnego nawiasu:

Map<Character, Color> map = new HashMap<Character, Color>() {{ 
  put(new Character('r'), Color.red);
  put(new Character('b'), Color.black );
}};
Hmm, jeśli ktoś oceni post w dół, byłoby miło, gdybyś otrzymał opinię. Wszyscy jesteśmy tutaj, aby się uczyć, prawda? Thomas
Podoba mi się ten. Ostatnio widziałem podobną konstrukcję w innym miejscu, ale ludzie sugerowali, aby nigdy nie używać anonimowej podklasy do zapisywania literałów. Nie zgadzam się. GhostCat
Osobiście nie głosowałem na ciebie, ale widzę dwa problemy z twoim kodem. Po pierwsze, utworzenie anonimowej podklasy tylko do inicjalizacji nie jest dobrą praktyką. Widziećstackoverflow.com/a/924536/581205 Po drugie, nie musisz ręcznie tworzyć nowej instancji Postaci, autoboxing robi to za Ciebie:put('r', Color.red); Natix
Powinien jednak używać valueOf we wszystkich klasach rodzimych. stolsvik
@Natix tak, inicjowanie podwójnego nawiasu nie jest naprawdę zalecane Po prostu wspomniałem o tym jako odpowiedź na pytanie OP. To prawda, że ​​istnieją o wiele lepsze rozwiązania, aby to osiągnąć. Poza tym, tworzącCharacter ręcznie (boks ręczny) lub używanie autoboxingu nie jest tak naprawdę powodem do obniżenia. To kwestia stylu i starałem się użyć jak największej ilości kodu OP, aby utrzymać zamieszanie na niskim poziomie. Thomas
0

Aby nieco rozwinąć odpowiedź Thomasa ... Mapa jest interfejsem i musi być utworzona przez jedną z powiązanych konkretnych implementacji (HashMap, TreeMap lub LinkedHashMap). Nadal jest to dobra praktyka; jednak zadeklarować zmienną referencyjną jako implementację interfejsu, a nie konkretny konkret, ponieważ zapewnia ona przyszłą elastyczność.

Jeśli chodzi o fragment kodu, myślę, że nadal potrzebujesz par Klucz-wartość zdefiniowanych po stronie przypisania deklaracji. Więc zmieniłbym:

Map<Character, Color> map = new HashMap<>() {{ 

do

Map<Character, Color> map = new HashMap<Character, Color>() {{ 
@ lmsurprenant nie możesz używać <> z anonimowymi klasami wewnętrznymi Jonas Alves
Nie, operator <> został dodany w Javie 1.7 jako cukier syntaktyczny, więc nie musisz być tak gadatliwy. lmsurprenant

Powiązane pytania