Danh sách Java 8 <V> vào Bản đồ <K, V>

968
Tom Cammann 2013-12-04 13:18.

Tôi muốn dịch Danh sách các đối tượng thành Bản đồ bằng cách sử dụng các luồng và lambdas của Java 8.

Đây là cách tôi viết nó trong Java 7 trở xuống.

private Map<String, Choice> nameMap(List<Choice> choices) {
        final Map<String, Choice> hashMap = new HashMap<>();
        for (final Choice choice : choices) {
            hashMap.put(choice.getName(), choice);
        }
        return hashMap;
}

Tôi có thể thực hiện điều này một cách dễ dàng bằng cách sử dụng Java 8 và Guava nhưng tôi muốn biết cách thực hiện việc này mà không có Guava.

Trong Ổi:

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, new Function<Choice, String>() {

        @Override
        public String apply(final Choice input) {
            return input.getName();
        }
    });
}

Và Guava với Java 8 lambdas.

private Map<String, Choice> nameMap(List<Choice> choices) {
    return Maps.uniqueIndex(choices, Choice::getName);
}

21 answers

1431
zapl 2013-12-04 13:30.

Dựa trên Collectorstài liệu, nó đơn giản như:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName,
                                              Function.identity()));
319
Ulises 2014-08-23 08:20.

Nếu khóa của bạn KHÔNG được đảm bảo là duy nhất cho tất cả các phần tử trong danh sách, bạn nên chuyển đổi nó thành một Map<String, List<Choice>>thay vìMap<String, Choice>

Map<String, List<Choice>> result =
 choices.stream().collect(Collectors.groupingBy(Choice::getName));
164
Ole 2015-02-28 21:18.

Sử dụng getName()làm khóa và Choicechính nó làm giá trị của bản đồ:

Map<String, Choice> result =
    choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
29
Emre Colak 2016-04-20 08:38.

Đây là một cái khác trong trường hợp bạn không muốn sử dụng Collectors.toMap ()

Map<String, Choice> result =
   choices.stream().collect(HashMap<String, Choice>::new, 
                           (m, c) -> m.put(c.getName(), c),
                           (m, u) -> {});
26
Sahil Chhabra 2018-08-17 20:45.

Hầu hết các câu trả lời được liệt kê, bỏ sót một trường hợp khi danh sách có các mục trùng lặp . Trong trường hợp đó có câu trả lời sẽ ném IllegalStateException. Tham khảo đoạn mã dưới đây để xử lý các bản sao danh sách :

public Map<String, Choice> convertListToMap(List<Choice> choices) {
    return choices.stream()
        .collect(Collectors.toMap(Choice::getName, choice -> choice,
            (oldValue, newValue) -> newValue));
  }
21
Renukeswar 2017-04-07 21:02.

Thêm một lựa chọn theo cách đơn giản

Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));
19
Piotr R 2017-10-21 03:06.

Ví dụ: nếu bạn muốn chuyển đổi các trường đối tượng thành ánh xạ:

Đối tượng ví dụ:

class Item{
        private String code;
        private String name;

        public Item(String code, String name) {
            this.code = code;
            this.name = name;
        }

        //getters and setters
    }

Và hoạt động chuyển đổi Danh sách thành Bản đồ:

List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));

Map<String,String> map = list.stream()
     .collect(Collectors.toMap(Item::getCode, Item::getName));
12
John McClean 2016-02-25 07:45.

Nếu bạn không phiền khi sử dụng các thư viện của bên thứ 3, cyclops-react lib của AOL (tiết lộ rằng tôi là người đóng góp) có các phần mở rộng cho tất cả các loại Bộ sưu tập JDK , bao gồm Danh sáchBản đồ .

ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);
11
Vikas Suryawanshi 2017-06-09 19:33.

Bạn có thể tạo Luồng các chỉ số bằng IntStream và sau đó chuyển đổi chúng thành Bản đồ:

Map<Integer,Item> map = 
IntStream.range(0,items.size())
         .boxed()
         .collect(Collectors.toMap (i -> i, i -> items.get(i)));
10
iZian 2016-01-09 00:43.

Tôi đã cố gắng thực hiện việc này và nhận thấy rằng, bằng cách sử dụng các câu trả lời ở trên, khi sử dụng Functions.identity()cho khóa Bản đồ, sau đó tôi gặp vấn đề với việc sử dụng phương thức cục bộ như this::localMethodNamethực sự hoạt động do vấn đề nhập.

Functions.identity()thực sự thực hiện điều gì đó đối với việc nhập trong trường hợp này, vì vậy phương thức sẽ chỉ hoạt động bằng cách trả về Objectvà chấp nhận một tham số củaObject

Để giải quyết điều này, tôi đã bỏ qua Functions.identity()và sử dụng s->sthay thế.

Vì vậy, mã của tôi, trong trường hợp của tôi để liệt kê tất cả các thư mục bên trong một thư mục và đối với mỗi thư mục, hãy sử dụng tên của thư mục làm khóa cho bản đồ và sau đó gọi một phương thức với tên thư mục và trả về một tập hợp các mục, trông giống như:

Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));
8
grep 2018-07-14 14:29.

Tôi sẽ viết cách chuyển đổi danh sách thành bản đồ bằng cách sử dụng genericđảo ngược kiểm soát . Chỉ là phương pháp phổ quát!

Có thể chúng ta có danh sách Số nguyên hoặc danh sách các đối tượng. Vì vậy, câu hỏi đặt ra là: điều gì nên là chìa khóa của bản đồ?

tạo giao diện

public interface KeyFinder<K, E> {
    K getKey(E e);
}

bây giờ sử dụng đảo ngược điều khiển:

  static <K, E> Map<K, E> listToMap(List<E> list, KeyFinder<K, E> finder) {
        return  list.stream().collect(Collectors.toMap(e -> finder.getKey(e) , e -> e));
    }

Ví dụ: nếu chúng ta có các đối tượng là sách, lớp này sẽ chọn khóa cho bản đồ

public class BookKeyFinder implements KeyFinder<Long, Book> {
    @Override
    public Long getKey(Book e) {
        return e.getPrice()
    }
}
6
user2069723 2015-04-25 09:31.

Tôi sử dụng cú pháp này

Map<Integer, List<Choice>> choiceMap = 
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));
5
Kumar Abhishek 2016-01-25 06:43.
Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
                .toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));
4
raja emani 2018-06-05 00:45.

Điều này có thể được thực hiện theo 2 cách. Hãy để mọi người là lớp học mà chúng tôi sẽ sử dụng để chứng minh điều đó.

public class Person {

    private String name;
    private int age;

    public String getAge() {
        return age;
    }
}

Hãy để mọi người là danh sách Những người được chuyển đổi sang bản đồ

1. sử dụng foreach đơn giản và biểu thức Lambda trên danh sách

Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));

2.Sử dụng Bộ sưu tập trên Luồng được xác định trên Danh sách nhất định.

 Map<Integer,List<Person>> mapPersons = 
           persons.stream().collect(Collectors.groupingBy(Person::getAge));
4
Konrad Borowski 2018-07-03 02:05.

Có thể sử dụng các luồng để làm điều này. Để loại bỏ nhu cầu sử dụng rõ ràng Collectors, bạn có thể nhập toMaptĩnh (theo khuyến nghị của Java hiệu quả, phiên bản thứ ba).

import static java.util.stream.Collectors.toMap;

private static Map<String, Choice> nameMap(List<Choice> choices) {
    return choices.stream().collect(toMap(Choice::getName, it -> it));
}
3
user_3380739 2017-06-09 17:51.

Đây là giải pháp của StreamEx

StreamEx.of(choices).toMap(Choice::getName, c -> c);
3
Rajeev Akotkar 2017-07-12 18:04.
Map<String,Choice> map=list.stream().collect(Collectors.toMap(Choice::getName, s->s));

Thậm chí phục vụ mục đích này cho tôi,

Map<String,Choice> map=  list1.stream().collect(()-> new HashMap<String,Choice>(), 
            (r,s) -> r.put(s.getString(),s),(r,s) -> r.putAll(s));
3
Vaneet Kataria 2019-01-23 08:28.

Nếu mọi giá trị mới cho cùng một tên khóa phải được ghi đè:

public Map < String, Choice > convertListToMap(List < Choice > choices) {
    return choices.stream()
        .collect(Collectors.toMap(Choice::getName,
            Function.identity(),
            (oldValue, newValue) - > newValue));
}

Nếu tất cả các lựa chọn phải được nhóm trong một danh sách cho một tên:

public Map < String, Choice > convertListToMap(List < Choice > choices) {
    return choices.stream().collect(Collectors.groupingBy(Choice::getName));
}
1
vaibhav 2019-08-23 17:16.
List<V> choices; // your list
Map<K,V> result = choices.stream().collect(Collectors.toMap(choice::getKey(),choice));
//assuming class "V" has a method to get the key, this method must handle case of duplicates too and provide a unique key.
0
Frank Neblung 2019-11-25 23:55.

Để thay thế cho guavamột người có thể sử dụng kotlin-stdlib

private Map<String, Choice> nameMap(List<Choice> choices) {
    return CollectionsKt.associateBy(choices, Choice::getName);
}
0
L. G. 2020-10-22 05:36.

Một khả năng khác chỉ xuất hiện trong các bình luận:

Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(c -> c.getName(), c -> c)));

Hữu ích nếu bạn muốn sử dụng một tham số của một đối tượng phụ làm Khóa:

Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(c -> c.getUser().getName(), c -> c)));

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Thời gian, sự kiên nhẫn, thời gian, sự cống hiến và thời gian chỉ là một vài trong số những thứ mà Peter Bellerby cần để thành lập và sau đó điều hành Bellerby & Co. Globemakers, một trong những công ty duy nhất trên Trái đất vẫn sản xuất các quả địa cầu bằng tay.

Năm giai đoạn đau buồn sau khi mất việc làm

Năm giai đoạn đau buồn sau khi mất việc làm

Đó là một ngày thứ Bảy, máy bay của tôi hạ cánh, và tôi đã sẵn sàng để thư giãn trong một kỳ nghỉ cuối tuần ngắn ngủi, khi một email đến trên điện thoại của tôi. Tôi đã mất việc.

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Nếu bạn đã từng bị đánh cắp danh tính của mình, bạn biết đó là một trải nghiệm đáng sợ và căng thẳng. Một cách không phổ biến để ngăn chặn nó? Tín dụng bị đóng băng.

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Eleanor (Kristen Bell) dường như đã tình nguyện cho chúng tôi làm vật tưởng nhớ. NBC's The Good Place là một chương trình thích thử thách tốt.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language