杰瑞科技汇

Java中List和Set如何互相转换?

ListSet

List 转换为 Set 最直接的方法就是使用 Set 的构造函数,这样做的主要目的是去除重复元素,因为 Set 集合中不允许有重复的元素。

Java中List和Set如何互相转换?-图1
(图片来源网络,侵删)

使用 HashSet 构造函数(最常用)

HashSet 是最常用的 Set 实现类,它不保证元素的顺序(插入顺序和遍历顺序可能不同)。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ListToSetExample {
    public static void main(String[] args) {
        // 1. 创建一个包含重复元素的 List
        List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
        System.out.println("原始 List: " + fruitList);
        // 2. 使用 HashSet 的构造函数将 List 转换为 Set
        // 这会自动去除重复的 "apple"
        Set<String> fruitSet = new HashSet<>(fruitList);
        System.out.println("转换后的 Set: " + fruitSet);
        // 输出可能是: [orange, grape, apple, banana] (顺序不固定)
    }
}

使用 LinkedHashSet 构造函数(保留插入顺序)

如果你希望在转换后保留原始 List 的插入顺序,应该使用 LinkedHashSet

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ListToSetPreserveOrder {
    public static void main(String[] args) {
        List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
        System.out.println("原始 List: " + fruitList);
        // 使用 LinkedHashSet 的构造函数
        Set<String> fruitSet = new LinkedHashSet<>(fruitList);
        System.out.println("转换后的 LinkedHashSet: " + fruitSet);
        // 输出: [apple, banana, orange, grape] (保留了插入顺序)
    }
}

使用 Java 8 Stream API

如果你想在转换的同时进行一些操作(如过滤),可以使用 Stream API。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ListToSetWithStream {
    public static void main(String[] args) {
        List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
        System.out.println("原始 List: " + fruitList);
        // 使用 Stream 去重并收集到 HashSet 中
        Set<String> fruitSet = fruitList.stream()
                                        .collect(Collectors.toSet());
        System.out.println("转换后的 Set (Stream): " + fruitSet);
        // 使用 Stream 收集到 LinkedHashSet 中以保留顺序
        Set<String> orderedFruitSet = fruitList.stream()
                                                .collect(Collectors.toCollection(LinkedHashSet::new));
        System.out.println("转换后的 LinkedHashSet (Stream): " + orderedFruitSet);
    }
}

SetList

Set 转换为 List 同样简单,通常使用 List 的构造函数,这样做的主要目的是允许重复元素支持 List 特有的操作(如按索引访问 get(i))。

Java中List和Set如何互相转换?-图2
(图片来源网络,侵删)

使用 ArrayList 构造函数(最常用)

这是最直接、最常用的方法。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SetToListExample {
    public static void main(String[] args) {
        // 1. 创建一个 Set
        Set<String> fruitSet = new HashSet<>(Arrays.asList("apple", "banana", "orange"));
        System.out.println("原始 Set: " + fruitSet);
        // 2. 使用 ArrayList 的构造函数将 Set 转换为 List
        List<String> fruitList = new ArrayList<>(fruitSet);
        System.out.println("转换后的 List: " + fruitList);
    }
}

使用 Java 8 Stream API

Stream API 提供了另一种灵活的方式。

import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
public class SetToListWithStream {
    public static void main(String[] args) {
        Set<String> fruitSet = new HashSet<>(Arrays.asList("apple", "banana", "orange"));
        System.out.println("原始 Set: " + fruitSet);
        // 使用 Stream 收集到 ArrayList 中
        List<String> fruitList = fruitSet.stream()
                                          .collect(Collectors.toList());
        System.out.println("转换后的 List (Stream): " + fruitList);
    }
}

总结与最佳实践

转换方向 常用方法 目的/特点 示例代码
List → Set new HashSet<>(list) 去重,不保证顺序 Set<String> set = new HashSet<>(myList);
new LinkedHashSet<>(list) 去重并保留插入顺序 Set<String> set = new LinkedHashSet<>(myList);
Set → List new ArrayList<>(set) 允许重复,支持索引访问 List<String> list = new ArrayList<>(mySet);

关键注意事项:

  1. 元素顺序

    • 当你从 List 转换到 Set 时,除了 LinkedHashSet,其他 Set 实现(如 HashSet, TreeSet不会保留原始 List 的插入顺序
    • 当你从 Set 转换到 List 时,List 的顺序取决于原始 Set 的迭代顺序,对于 HashSet,顺序也是不确定的;对于 LinkedHashSet,顺序是其插入顺序;对于 TreeSet,顺序是其排序顺序。
  2. 空集合

    • 如果传入的 ListSetnull,使用构造函数会抛出 NullPointerException,在转换前最好进行判空处理。
      List<String> myList = ...; // 可能是 null
      Set<String> mySet = myList != null ? new HashSet<>(myList) : new HashSet<>();
  3. 性能

    • 使用构造函数进行转换通常是最直接且性能较好的方式,时间复杂度通常是 O(n),n 是集合中的元素数量。
    • Stream API 提供了极大的灵活性,特别是在需要结合 filter, map 等中间操作时,但对于简单的转换,构造函数更简洁高效。
分享:
扫描分享到社交APP
上一篇
下一篇