如何在Java中将Set转换为List

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

HashSet的add()方法将元素添加到集合中。请注意,这些元素是不重复的。由于集合是无序的,所以无法按照插入顺序获取元素。

在Java中将Set转换为List

让我们将集合转换为列表。有多种方法可以做到这一点。每种方法都与其他方法不同,而且这些差异是微妙的。

用集合参数的列表构造函数

将集合转换为列表的最直接的方法是在创建列表时将集合作为参数传递。这样调用构造函数,从那里开始构造函数就会自行处理剩下的部分。

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

    }
}
Using Constructor

由于集合已经转换为列表,元素现在是有序的。这意味着我们可以使用 get() 方法通过索引访问元素。

使用传统的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));
    }   
}
Using for-loop

For循环按照集合中的元素逐个进行遍历,并将元素添加到列表中。

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));
    }
}
Using addAll()

4. Stream API collect()方法

Stream 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));
    }
}
using stream.collect()

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()方法。该方法返回一个不可修改的列表,其中包含给定集合的元素,并按照迭代顺序排列。列表中不允许包含任何空元素。如果集合中包含有”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));
    }
}
using List.copyOf()

在集合中添加一个空值,并尝试将其转换为列表。

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));
    }
}
Null Pointer Exception

当您尝试将元素添加到不可变列表时,您将收到以下类似的错误提示。

Immutable Error

使用addAll()方法将包含空元素的集合转换为列表:

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));
    }
}
AddAll() with Null

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

结论是

我们看到了一些非常有趣的方法将一个集合转换为列表。关注从每个方法创建的列表类型非常重要。例如,copyOf()方法产生一个不可变的列表,不能处理空元素。而stream.collect()方法没有任何保证。构造函数和addAll()方法是批处理中最可信赖的。