2015-05-20 14 views
7

Tôi có hai mảng Chuỗi. Một người có tên ngắn.Làm thế nào để ánh xạ hai mảng thành một HashMap trong Java?

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

Tên khác có tên dài.

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

Cả hai đều có cùng số thành phần. Làm thế nào tôi có thể ánh xạ tên ngắn là KEY và tên dài là VALUE trong HashMap?

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

Tôi biết, tôi có thể thực hiện bằng cách lặp. Có cách nào tốt hơn?

+0

Tôi nghĩ rằng vòng lặp là cách tốt nhất trong bối cảnh này - khi kích thước của hai mảng này là như nhau. – Razib

+0

Tại sao lưu trữ trong mảng ở nơi đầu tiên? –

Trả lời

14

Có nhiều cách bạn có thể thực hiện việc này. Một trong đó là khá dễ dàng để hiểu và áp dụng được sử dụng Java 8 con suối và nhà sưu tập bản đồ từ một dòng chỉ số cho các cặp giá trị key:

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

Có một số bên thứ ba thư viện Java bao gồm một 'zip' chức năng để lấy hai luồng và tạo một bản đồ từ cái này sang cái khác. Nhưng thực sự họ chỉ là những cách đơn giản để đạt được điều tương tự như mã ở trên.

+0

và những gì về java 7 và dưới đây? –

+0

@ 10sw33 Dưới đây là Java 8 (ngoài việc nâng cấp!), Bạn vẫn còn một vài tùy chọn. Sử dụng thư viện của bên thứ ba hoặc sử dụng 'Arrays.toList (shortNames) .forEach' để đi qua tất cả các mục trong một mảng và thêm các mục bản đồ. Tôi biết điều này thực sự chỉ là lặp lại bởi một tên khác nhưng sau đó cũng như vậy là các luồng! – sprinter

+0

@sprinter Câu trả lời hay, nhưng anh ta cần đóng hộp() như Jens nói dưới đây. –

1

accepted answer không hoạt động đối với tôi, vì IntStream không cung cấp phương thức collect một đối số.

Để được hưởng lợi từ bộ sưu tập toMap, trước tiên bạn phải đặt các đối tượng địa lý int thành Integer đối tượng. Nếu bạn muốn giữ gìn trật tự nguyên tố, sử dụng các phiên bản mở rộng của toMap cùng với LinkedHashMap::new như hình dưới đây:

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); 
    } 
} 

xem thêm: Why don't primitive Stream have collect(Collector)?

1

Bạn có thể sử dụng org.apache.commons.lang3.ArrayUtils.

Dưới đây là một ví dụ:

Map colorMap = ArrayUtils.toMap(new String[][] { 
    {"RED", "#FF0000"}, 
    {"GREEN", "#00FF00"}, 
    {"BLUE", "#0000FF"}}); 
Các vấn đề liên quan