2015-05-20 11 views
7

Mam dwa tablice String. Jeden o krótkiej nazwie.Jak odwzorować dwie tablice na jedną HashMap w Javie?

// days short name 
String[] shortNames = {"SUN", "MON", "...", "SAT"}; 

Drugie z długimi nazwami.

// days long name 
String[] longNames = {"SUNDAY", "MONDAY", "....", "SATURDAY"}; 

Obie mają taką samą liczbę elementów. Jak mogę zamapować krótką nazwę jako KEY i długą nazwę jako VALUE w HashMap?

HashMap<String, String> days = new HashMap<>(); 

Wiem, mogę zrobić przez zapętlenie. Czy istnieje lepszy sposób?

+0

myślę zapętlenie jest najlepszy sposób w tym kontekście - gdy wielkość tych dwóch tablic są takie same. – Razib

+0

Dlaczego warto przechowywać w tablicy? –

Odpowiedz

14

Istnieje wiele sposobów na zrobienie tego. Jednym z nich jest dość łatwy do zrozumienia i zastosowania się używając Java 8 strumieni i kolektory do mapy ze strumienia indeksów dla par wartości klucza:

Map<String, String> days = IntStream.range(0, shortNames.length).boxed() 
    .collect(Collectors.toMap(i -> shortNames[i], i -> longNames[i])); 

Istnieje kilka firm biblioteki Java trzecie, które zawierają „zip” funkcję do weź dwa strumienie i stwórz mapę od jednego do drugiego. Ale tak naprawdę są one po prostu starszymi sposobami osiągnięcia tego samego, co powyższy kod.

+0

i co z Java 7 i niżej? –

+0

@ 10sw33 Poniżej Java 8 (oprócz aktualizacji!) Nadal masz kilka opcji. Użyj biblioteki innej firmy lub użyj 'Arrays.toList (shortNames) .forEach', aby przejrzeć wszystkie elementy w jednej tablicy i dodać pozycje mapy. Wiem, że jest to po prostu iteracja pod innym nazwiskiem, ale także strumienie! – sprinter

+0

@sprinter Dobra odpowiedź, ale potrzebuje boksowania(), jak powiedział Jens poniżej. –

1

Nie działa dla mnie accepted answer, ponieważ IntStream nie zapewnia jednokrotnej metody collect.

Aby jednak skorzystać z kolektora toMap, należy najpierw spakować prymitywy int w obiekty Integer. Jeśli chcesz zachować kolejność elementów, użyj rozszerzoną wersję toMap wraz z LinkedHashMap::new jak pokazano poniżej:

package learning.java8; 

import static java.util.stream.Collectors.*; 
import static org.junit.Assert.*; 

import java.time.DayOfWeek; 
import java.time.format.TextStyle; 
import java.util.Arrays; 
import java.util.LinkedHashMap; 
import java.util.Locale; 
import java.util.Map; 
import java.util.stream.IntStream; 

import org.junit.Test; 

public class IntStreamLT { 

    @Test 
    public void q30339679() { 

     final String[] shortNames = getDayOfWeekNamesInEnglish(TextStyle.SHORT); 
     final String[] longNames = getDayOfWeekNamesInEnglish(TextStyle.FULL); 

     final Map<String, String> days = IntStream.range(0, shortNames.length).boxed() 
       .collect(toMap(i -> shortNames[i], i -> longNames[i])); 

     System.out.println(days); 

     final Map<String, String> sorted = IntStream.range(0, shortNames.length).boxed() 
       .collect(toMap(
         i -> shortNames[i], i -> longNames[i], 
         (i, j) -> i, LinkedHashMap::new)); 

     System.out.println(sorted); 

     assertEquals("{Mon=Monday, Tue=Tuesday, Wed=Wednesday, Thu=Thursday, " 
       + "Fri=Friday, Sat=Saturday, Sun=Sunday}", sorted.toString()); 
    } 

    private static String[] getDayOfWeekNamesInEnglish(final TextStyle style) { 

     return Arrays.stream(DayOfWeek.values()) 
       .map(day -> day.getDisplayName(style, Locale.ENGLISH)) 
       .toArray(String[]::new); 
    } 
} 

zobacz także: Why don't primitive Stream have collect(Collector)?

1

Można użyć org.apache.commons.lang3.ArrayUtils.

Oto przykład:

Map colorMap = ArrayUtils.toMap(new String[][] { 
    {"RED", "#FF0000"}, 
    {"GREEN", "#00FF00"}, 
    {"BLUE", "#0000FF"}}); 
Powiązane problemy