使用 JDK 8 将List转换为Map

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(97)   2024-06-07 06:21:34

我曾多次遇到这种情况,希望将多个对象存储在 Map 而不是 SetList 中,因为有一些优势 使用对象的唯一标识信息的Map。 Java 8 通过流和 Collectors.toMap(…) 方法使这种转换比以往任何时候都更容易。

使用 Map 而不是 Set 的一种情况是在处理缺少或具有粗略 equals(Object)hashCode() 实现,但确实有一个唯一标识对象的字段。在那些情况下,如果我不能添加或修复对象的底层实现,我可以通过使用类的唯一标识字段(键)的 Map 到类的实例化对象(价值)。当我更喜欢 Map 而不是 ListSet 时,可能更常见的情况是我需要通过特定的唯一标识字段查找集合中的项目.在唯一标识键上进行映射查找速度很快,而且通常比依赖迭代和比较每个对象调用 equals(Object) 方法快得多。

使用 JDK 8,从现有的 MapList 构建 Set 比以往任何时候都容易。为了帮助演示这一点,将使用一个简单的 Book 类。此 Book 类不会覆盖 equals(Object) 类中的 hashCode()Object,因此不是适合使用的类在 Set 中或作为 Map 键。但是,它的 getIsbn() 方法会返回一个 International Standard Book Number,在本演示中假定该编号是唯一的。

Book.java

package dustin.examples.jdk8;

/**
 * Represents a book, but does not override {@code equals(Object)}
 * or {@code hashCode()}.
 */
public class Book
{
   /** International Standard Book Number (ISBN-13). */
   final String isbn;

   /** Title of book. */
   final String title;

   /** Edition of book. */
   final int edition;

   /**
    * Constructor.
    *
    * @param newIsbn International Standard Book Number (-13).
    * @param newTitle Title.
    * @param newEdition Edition.
    */
   public Book(final String newIsbn, final String newTitle, final int newEdition)
   {
      isbn = newIsbn;
      title = newTitle;
      edition = newEdition;
   }

   /**
    * Provide ISBN-13 identifier associated with this book.
    *
    * @return ISBN-13 identifier.
    */
   public String getIsbn()
   {
      return isbn;
   }

   /**
    * Provide title of this book.
    *
    * @return Book's title.
    */
   public String getTitle()
   {
      return title;
   }

   /**
    * Provide edition of this book.
    *
    * @return Book's edition.
    */
   public int getEdition()
   {
      return edition;
   }

   @Override
   public String toString()
   {
      return title + " (Edition " + edition + ") - ISBN-13: " + isbn;
   }
}

有了这个类,演示类 CollectionToMapDemo 展示了使用 JDK 8 转换各种 Java 集合类型(SetList、甚至数组)到 Map

CollectionToMapDemo.java

package dustin.examples.jdk8;

import static java.lang.System.out;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Demonstrates conversion of Java collections to Java Maps.
 */
public class CollectionToMapDemo
{
   /**
    * Multiple instances of Book, a class that lacks a proper
    * equals(Object) method, but for which its getIsbn() method
    * is assumed to return a unique identifier for each instance.
    */
   private static final Book[] books;

   static
   {
      books = new Book[]
         {
            new Book("978-0-201-31005-4", "Effective Java", 1),
            new Book("978-0-321-35668-0", "Effective Java", 2),
            new Book("978-0-13-468599-1", "Effective Java", 3)
         };
   }

   /**
    * Convert provided array of Book instances to Map of each Book's ISBN to
    * that instance of the Book.
    * 
    * @param booksArray Array of Book instances.
    * @return Map of each book's ISBN (key) to the book's full instance (value).
    */
   private static Map<String, Book> convertArrayToMap(final Book[] booksArray)
   {
      return Arrays.stream(books).collect(
         Collectors.toMap(Book::getIsbn, book -> book));
   }

   /**
    * Convert provided List of Book instances to Map of each Book's ISBN to
    * that instance of the Book.
    *
    * @param booksList List of Book instances.
    * @return Map of each book's ISBN (key) to the book's full instance (value).
    */
   private static Map<String, Book> convertListToMap(final List<Book> booksList)
   {
      return booksList.stream().collect(
         Collectors.toMap(Book::getIsbn, book -> book));
   }

   /**
    * Convert provided Set of Book instances to Map of each Book's ISBN to
    * that instance of the Book.
    *
    * @param booksSet Set of Book instances.
    * @return Map of each book's ISBN (key) to the book's full instance (value).
    */
   private static Map<String, Book> convertSetToMap(final Set<Book> booksSet)
   {
      return booksSet.stream().collect(
         Collectors.toMap(Book::getIsbn, book -> book));
   }

   public static void main(final String[] arguments)
   {
      out.println("ARRAY->MAP:\n" + convertArrayToMap(books));

      final List<Book> booksList = Arrays.asList(books);
      out.println("LIST->MAP:\n" + convertListToMap(booksList));

      final Set<Book> booksSet
         = new HashSet<>(Arrays.stream(books).collect(Collectors.toSet()));
      out.println("SET->MAP:\n" + convertSetToMap(booksSet));
   }
}

刚刚显示的类列表中最重要的方法是 convertArrayToMap(Book[])convertListToMap(List<Book>)convertSetToMap(Set<Book>)。一旦访问了基于底层 SetList 或数组的 stream,所有这三种实现都是相同的。在所有这三种情况下,这只是使用 streamcollect() 方法之一的问题(一个 reduction operator 通常是 < span>优于顺序迭代),并向其传递 Collector 接口的实现,该实现是通过来自 Collectors 的预定义 toMap() 收集器提供的类

针对 Book 的实例运行此演示类的输出如下所示:

ARRAY->MAP:
{978-0-201-31005-4=Effective Java (Edition 1) - ISBN-13: 978-0-201-31005-4, 978-0-321-35668-0=Effective Java (Edition 2) - ISBN-13: 978-0-321-35668-0, 978-0-13-468599-1=Effective Java (Edition 3) - ISBN-13: 978-0-13-468599-1}
LIST->MAP:
{978-0-201-31005-4=Effective Java (Edition 1) - ISBN-13: 978-0-201-31005-4, 978-0-321-35668-0=Effective Java (Edition 2) - ISBN-13: 978-0-321-35668-0, 978-0-13-468599-1=Effective Java (Edition 3) - ISBN-13: 978-0-13-468599-1}
SET->MAP:
{978-0-201-31005-4=Effective Java (Edition 1) - ISBN-13: 978-0-201-31005-4, 978-0-321-35668-0=Effective Java (Edition 2) - ISBN-13: 978-0-321-35668-0, 978-0-13-468599-1=Effective Java (Edition 3) - ISBN-13: 978-0-13-468599-1}

我遇到过几种情况,在这些情况下,在具有唯一标识符的 Map 中拥有多个对象对于这些对象的完整实例是有利的,但是在 SetList 或数组。尽管在 Java 中将这些 SetList 和数组转换为 Map 从来都不是特别困难,但在 Java 中却比以往任何时候都容易8 进行此转换。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-converting-collections-maps-jdk-8.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...