序言
数组、Set、List、Map是Java语言非常常用的几种数据类型,他们之间存在着千丝万缕的联系。关于底层的数据结构我这里就不再多说啦,直接从应用出发,总结他们之间的转换方法,并给出推荐方法。
大家可以点赞收藏等到需要的时候随时回顾查看使用!!!
如果将他们每两个类型的转换方式都总结一遍的,一共四种类型,再加上来回转换,每个转换都假设只讲一个方法,就要总结32次,因此这次不一一全部总结,采用递进方式,关系最接近的两个类型之间逐一转换讲解:
数组↔List(ArrayList)↔Set(HashSet)↔Map(HashMap)
1.数组与List(ArrayList)的转换
1.1数组——>List(ArrayList)
定义数组为
int[] array = {2,0,0,1,5,2,6,7};
1.常规遍历
/**
* 整数数组通过循环遍历的方式,将元素逐一插入List中
* @param array
*/
public static List<Integer> arrayToListFor(int[] array){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
list.add(array[i]);
}
// 输出list内容
System.out.println(list);
// 输出list的类型
System.out.println(list.getClass());
return list;
}
输出结果:
[2, 0, 0, 1, 5, 2, 6, 7]
class java.util.ArrayList
2.jdk1.8的新特性stream流转换(推荐)
如果是int基本数据类型则要多进行一步装箱,Integer类型则不需要,直接toList()即可。
/**
*利用java8的stream流将数组转换为List
*/
public static void arrayToListStream(){
int[] array = {2,0,0,1,5,2,6,7};
Integer[] array1 = {5,2,6,7,2,0,0,1};
// 基本数据类型利用stream流转成List,需要先对int数据类型调用boxed()方法进行装箱再转换
List<Integer> intList = Arrays.stream(array).boxed().collect(Collectors.toList());
List<Integer> integerList = Arrays.stream(array1).collect(Collectors.toList());
// 输出intList内容
System.out.println(intList);
// 输出integerList内容
System.out.println(integerList);
// 输出intList的类型
System.out.println(intList.getClass());
// 输出integerList的类型
System.out.println(integerList.getClass());
}
上述代码输出结果:
[2, 0, 0, 1, 5, 2, 6, 7]
[5, 2, 6, 7, 2, 0, 0, 1]
class java.util.ArrayList
class java.util.ArrayList
4.直接使用Arrays.asList(数组)方法
5.使用List.of(数组)
6.利用ArrayList<>()构造方法结合前两种方法的其中一种
public static void listToArray(){
// 利用Arrays.asList()方法将数组转换为List
Integer[] array = {2,0,0,1,5,2,6,7};
List<Integer> list1 = Arrays.asList(array);
System.out.println(list1);
System.out.println(list1.getClass());
// 利用List.of()方法将数组转换为List
List<Integer> list2 = List.of(array);
System.out.println(list2);
System.out.println(list2.getClass());
// 利用ArrayList的构造方法将数组转换为List
List<Integer> list3 = new ArrayList<>(List.of(array));
System.out.println(list3);
System.out.println(list3.getClass());
}
[2, 0, 0, 1, 5, 2, 6, 7]
class java.util.Arrays$ArrayList
[2, 0, 0, 1, 5, 2, 6, 7]
class java.util.ImmutableCollections$ListN
[2, 0, 0, 1, 5, 2, 6, 7]
class java.util.ArrayList
从结果可以看出,虽然最终都转成了List,但是却是不同的List类型。java.util.Arrays\$ArrayList
、java.util.ImmutableCollections\$ListN
和 java.util.ArrayList
是 Java 中三种不同的列表实现类,它们有一些区别。
java.util.Arrays$ArrayList 是 Arrays 类的静态内部类,它是 Arrays 类使用asList方法返回的 List 实现,这个列表是固定大小的,不能进行添加或删除元素的操作。
java.util.ImmutableCollections$ListN 是 Java 9 引入的不可变 List 实现,它是不可变的、固定大小的列表,因此也不能进行元素的添加或删除操作。
java.util.ArrayList 是 Java 中最常用的动态数组实现,它是一个可变大小的数组,可以根据需要动态增长或缩小,并且支持多种操作。
1.2List——>数组
简单的循环遍历加入到数组中这里就不再重新写一遍了。
1.使用stream流转换推荐
使用流(Stream)和方法引用(Method Reference)将 List 转换为 int 数组
public static void listToArray(){
List<Integer> list = new ArrayList<>(List.of(5,2,6,7,2,0,0,1));
// 使用流(Stream)和方法引用(Method Reference)将 List<Integer> 转换为 int 数组
int[] intArray = list.stream().mapToInt(Integer::intValue).toArray();
// 输出转换后的 int 数组
for (int value : intArray) {
System.out.print(value+",");
}
System.out.println();
System.out.println(intArray.getClass());
}
结果如下:
5,2,6,7,2,0,0,1,
class [I
2. List(ArrayList)与Set的转换
List是元素有序且可重复的列表,Set是元素无序且不可重复的集合,他们之间可以互相转换。
2.1List(ArrayList)——>Set集合
1.for循环一个一个加入到set中,这里就不再演示
2.HashSet构造器传入List推荐
/**
*HashSet构造器传入List
*/
public static void listToSetStream(){
List<Integer> list = new ArrayList<>(List.of(5,2,6,7,2,0,0,1));
Set<Integer> set = new HashSet<>(list);
// 输出set内容
System.out.println(set);
// 输出set的类型
System.out.println(set.getClass());
}
结果如下:可以看到类型为我们想要的HashSet,元素也进行了去重且和List顺序不一致。
[0, 1, 2, 5, 6, 7]
class java.util.HashSet
3.使用stream流
public static void listToSetStream(){
List<Integer> list = new ArrayList<>(List.of(5,2,6,7,2,0,0,1));
Set<Integer> set = list.stream().collect(Collectors.toSet());
// 输出转换后的Set内容
System.out.println(set);
// 输出转换后的Set的类型
System.out.println(set.getClass());
}
结果和第二种方法一样。并且根据IDEA提示,其推荐将该方法直接替换成第二种构造器的方法。因此第二种更推荐。
2.1Set——>List(ArrayList)
1.List构造器方法推荐
public static void setToList(){
Set<Integer> set = new HashSet<>(Set.of(5,2,6,7,0,1));
List<Integer> list = new ArrayList<>(set);
// 输出转换后的List内容
System.out.println(list);
// 输出转换后的List的类型
System.out.println(list.getClass());
}
输出结果:
[0, 1, 2, 5, 6, 7]
class java.util.ArrayList
2.stream流
public static void setToListStream(){
Set<Integer> set = new HashSet<>(Set.of(5,2,6,7,0,1));
List<Integer> list = set.stream().collect(Collectors.toList());
System.out.println(list);
System.out.println(list.getClass());
}
同样,IDEA也给出提示,推荐使用ArrayList构造器方法。
2. Set与Map的转换
2.1 Set——>Map
由于Map是键值对,Set是单个元素值,所以转换时需要指定键和值,这里我指定set的值为Map的键,字符串value+值作为Map的值。
1.stream流推荐
public static void setToMap(){
Set<Integer> set = new HashSet<>(List.of(1,2,3,4,5));
Map<Integer, String> map = set.stream().collect(Collectors.toMap(i -> i, i -> "value"+i));
System.out.println(map);
System.out.println(map.getClass());
}
结果如下:
{1=value1, 2=value2, 3=value3, 4=value4, 5=value5}
class java.util.HashMap
2.循环put,这里不再赘述
Map——>Set
因为Map是键值对,因此转换成Set有两种情况,
1.将Map的全部键转为Set
public static void mapToSet(){
Map<Integer,String> map = new HashMap<>();
map.put(1,"value1");
map.put(2,"value2");
map.put(3,"value3");
map.put(4,"value4");
Set<Integer> keys = map.keySet();
System.out.println(keys);
System.out.println(keys.getClass());
}
结果如下:
[1, 2, 3, 4]
class java.util.HashMap$KeySet
可以看到转换得到的类型并不是最纯正的HashSet。HashMap$KeySet这个类是 HashMap 的一个视图(View),它表示该 HashMap 中的键集合。它并不是一个独立的类,而是与 HashMap 实例相关联的。当你从 HashMap 中获取键集时(例如通过 map.keySet()),你得到的是一个视图,该视图反映了 HashMap 中当前的键。如果 HashMap 中的键发生变化(添加、删除或修改),那么通过 keySet() 获取的视图也会相应地更新。例如如下:
2.如果要转成不与HashMap关联的Set,则用新的HashSet的构造器接住该KeySet推荐
如下:
2.将Map的全部值转为Set
1.stream流,利用map.values().stream()
public static void mapGetValues(){
Map<Integer,String> map = new HashMap<>();
map.put(1,"value1");
map.put(2,"value2");
map.put(3,"value3");
map.put(4,"value4");
Set<String> values = map.values().stream().collect(Collectors.toSet());
System.out.println(values);
System.out.println(values.getClass());
map.put(6,"value6");
System.out.println(values);
}
结果如下:
[value2, value1, value4, value3]
class java.util.HashSet
[value2, value1, value4, value3]
2.同样使用HashSet的构造器接住map.values()的返回值
public static void mapGetValues(){
Map<Integer,String> map = new HashMap<>();
map.put(1,"value1");
map.put(2,"value2");
map.put(3,"value3");
map.put(4,"value4");
// 构造器接住。
Set<String> values = new HashSet<>(map.values());
System.out.println(values);
System.out.println(values.getClass());
map.put(6,"value6");
System.out.println(values);
}
总结
综上,已经总结了常用的几个集合类型之间的转换方法,大家可以根据自己的需求选择,像常见的构造器转换方法和stream流方法都比较推荐。大家可以多多实践,便可深刻掌握。