杰瑞科技汇

Java List与Set如何高效转换?

  • List (列表): 有序、可重复,允许存储多个 null 值。ArrayList, LinkedList
  • Set (集合): 无序(HashSet)、不重复,只允许存储一个 null 值。HashSet, TreeSet

转换的关键在于利用它们的构造函数Java 8 Stream API

Java List与Set如何高效转换?-图1
(图片来源网络,侵删)

核心转换方法

List 转 Set

这是最常见的转换,通常目的是为了去重

使用 Set 的构造函数(最直接)

这是最简单、最常用的方法,直接使用 Set 的实现类(如 HashSet)的构造函数,该构造函数接受一个 CollectionList 实现了 Collection)作为参数。

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"));
        // 2. 使用 HashSet 的构造函数将 List 转换为 Set
        //    Set 的特性会自动去除重复的 "apple"
        Set<String> fruitSet = new HashSet<>(fruitList);
        // 3. 打印结果
        System.out.println("原始 List: " + fruitList); // [apple, banana, orange, apple, grape]
        System.out.println("转换后的 Set: " + fruitSet); // [orange, grape, apple, banana] (顺序可能不同)
    }
}

特点:

  • 优点: 代码简洁,一行搞定。
  • 缺点: 默认使用 HashSet,无法保证元素的顺序,如果你需要保持顺序,应该使用 LinkedHashSet

使用 Java 8 Stream API(更灵活)

Stream API 提供了更强大的转换和过滤能力。

Java List与Set如何高效转换?-图2
(图片来源网络,侵删)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class ListToSetStreamExample {
    public static void main(String[] args) {
        List<String> fruitList = new ArrayList<>(Arrays.asList("apple", "banana", "orange", "apple", "grape"));
        // 使用 Stream 的 collect 方法将 List 转换为 Set
        Set<String> fruitSet = fruitList.stream()
                                        .collect(Collectors.toSet());
        System.out.println("原始 List: " + fruitList);
        System.out.println("转换后的 Set: " + fruitSet); // 顺序可能不同
    }
}

特点:

  • 优点: 非常灵活,可以在转换前进行过滤、映射等操作。
  • 缺点: 代码稍显冗长,但对于复杂场景非常有用。

保持顺序的转换(使用 LinkedHashSet

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

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

Set 转 List

转换的目的是为了获得有序的列表,或者允许重复操作。

使用 List 的构造函数(最直接)

ListSet 类似,直接使用 List 的实现类(如 ArrayList)的构造函数。

Java List与Set如何高效转换?-图3
(图片来源网络,侵删)
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"));
        // 2. 使用 ArrayList 的构造函数将 Set 转换为 List
        List<String> fruitList = new ArrayList<>(fruitSet);
        // 3. 打印结果
        System.out.println("原始 Set: " + fruitSet); // [orange, apple, banana] (顺序可能不同)
        System.out.println("转换后的 List: " + fruitList); // [orange, apple, banana] (顺序与 Set 一致)
    }
}

特点:

  • 优点: 代码简洁,直接转换。
  • 缺点: 转换后的 List 的顺序取决于 Set 的具体实现(HashSet 无序,LinkedHashSet 有序)。

使用 Java 8 Stream API(更灵活)

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

特点:

  • 优点: 同样非常灵活,可以在转换前对元素进行处理。

总结与对比

转换方向 方法 示例代码 特点
List → Set 构造函数 Set<T> set = new HashSet<>(list); 最常用,简洁,默认去重,不保证顺序
Stream API Set<T> set = list.stream().collect(Collectors.toSet()); 灵活,可链式操作,默认去重,不保证顺序
保持顺序 Set<T> set = new LinkedHashSet<>(list); 使用 LinkedHashSet,去重且保持插入顺序
Set → List 构造函数 List<T> list = new ArrayList<>(set); 最常用,简洁,将 Set 的元素放入 List
Stream API List<T> list = set.stream().collect(Collectors.toList()); 灵活,可链式操作。

最佳实践建议

  1. 简单转换:如果只是简单地、一次性地在 ListSet 之间转换,直接使用构造函数 是最清晰、最高效的选择。

    • ListSet 去重:new HashSet<>(myList)
    • SetListnew ArrayList<>(mySet)
  2. 需要顺序ListSet 后需要保持原始顺序,务必使用 new LinkedHashSet<>(myList)

  3. 复杂处理:如果转换过程中需要包含过滤、映射、条件判断等复杂逻辑,或者代码风格倾向于函数式编程,那么使用 Java 8 Stream API 是更好的选择。

希望这份详细的解释能帮助你完全理解 Java 中 ListSet 的转换!

分享:
扫描分享到社交APP
上一篇
下一篇