如何在Java中将集合转换为列表

时间:2020-02-23 14:34:41  来源:igfitidea点击:

Java中的列表是数据的有序集合,而集合是数据的无序集合。
列表可以有重复的条目,而集合则不能。
两种数据结构在不同的情况下都是有用的。

知道如何将集合转换为列表很有用。
它可以将无序数据转换为有序数据。

初始化集合

让我们初始化一个集合并向其中添加一些元素。

import java.util.*;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);
      System.out.println(a);
  }
}

HashSet的add()方法将元素添加到集合中。
请注意,元素是不同的。
由于元素集是无序的,因此无法根据元素的插入顺序来获取元素。

用Java将集合转换为列表

让我们将集合转换为列表。
这样做有多种方法。
每种方式都彼此不同,这些差异是细微的。

1.带有Set参数的列表构造函数

将集合转换为列表的最直接方法是在创建列表时将集合作为参数传递。
这将调用构造函数,然后再由构造函数负责其余的工作。

import java.util.*;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr = new ArrayList<>(a);
   System.out.println(arr);
   System.out.println(arr.get(1));

  }
}

输出

由于已将集合转换为列表,因此现在对元素进行排序。
这意味着我们可以使用get()方法按索引访问元素。

2.使用常规的for循环

我们可以使用老式的for循环将元素从集合中显式复制到列表中。

import java.util.*;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr = new ArrayList<>(a);
      for (int i : a)
          arr.add(i);
      System.out.println(arr);
      System.out.println(arr.get(1));
  }   
}

For循环逐个遍历set元素,然后将元素添加到列表中。

3.列出addAll()方法

列表具有一个名为addAll()的方法,该方法可一次将多个值添加到列表中。
您可能会通过合并两个列表来回忆起该操作。
addAll()也可用于将集合的元素添加到列表中。

import java.util.*;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr = new ArrayList<>();
      arr.addAll(a);
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

4.流API collect()方法

从Java 8开始可以使用Stream.collect()。
ToList收集器将所有Stream流元素收集到List实例中。

import java.util.*;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr;

      arr = a.stream().collect(Collectors.toList());
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

stream.collect()的文档提到不能保证返回的List的类型,可变性,可序列化性或者线程安全性。
如果需要对返回的List进行更多控制,请使用toCollection(Supplier)。

要指定列表的类型,请使用toCollection(ArrayList :: new)

import java.util.*;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr;

arr = a.stream().collect(Collectors.toCollection(ArrayList::new));
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

推荐读物:Java流

5. List.copyOf()方法

Java 10及更高版本的List具有copyOf()方法。
该方法以迭代顺序返回包含给定Collection元素的不可修改的List。
该列表不能包含任何null元素。
如果集合包含" null",则该方法将返回null指针异常。

import java.util.*;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);

   List<Integer> arr;

      arr = List.copyOf(a);
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

在集合中添加null并尝试转换为列表:

import java.util.*;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);
      a.add(null);

   List<Integer> arr;

      arr = List.copyOf(a);
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

空指针异常

如果您尝试将元素添加到不可变列表中,则会收到类似于以下内容的错误。

不变错误

使用addAll()方法将具有null元素的set转换为列表:

import java.util.*;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args)
  {
      Set<Integer> a = new HashSet<>();
      a.add(1);
      a.add(2);
      a.add(3);
      a.add(1);
      a.add(null);

   List<Integer> arr = new ArrayList<>();
   arr.addAll(a);

    // arr = List.copyOf(a);
      System.out.println(arr);
      System.out.println(arr.get(1));
  }
}

请注意,空值出现在列表的开头。