Java中Array、List、Set、Map之间的各种转换

1.array 转 list

1.1 利用Arrays的public static <T> List<T> asList(T... a)方法:
在asList方法的内部,new 了一个ArrayList对象,将数组类型的参数a赋值给了ArrayList里面存储变量的数组(ArrayList本身也就是一个数组)。
在这里插入图片描述
在这里插入图片描述
需要注意的是: Arrays.asList() 返回一个受指定数组决定的固定大小的列表。所以不能做 add 、 remove 等操作,否则会报错。
具体代码:

		String[] arr = new String[] { "a", "b", "c", "d", "e" };

		List<String> list = Arrays.asList(arr);
		System.out.println(list);
		// 这里如果对上面list操作会报错
		list.add("f");// java.lang.UnsupportedOperationException

		/*
		 * 那如果我们想要增删要怎么办?
		 */

		// 利用下面这种方式就OK,再对list1操作
		List<String> list1 = new ArrayList<String>(Arrays.asList(arr));
		System.out.println(list1 );

1.2 利用最原始的boolean add(E e)方法:
new一个ArrayList时,虚拟机不会为其分配内存,往里面添加元素时,虚拟机才会分配一个初始容量为10的数组用来存放list的元素,每次add添加一个新的元素,都会检查一下添加元素后的长度是否大于ArrayList的容量,如果大于的话,就会为ArrayList扩容,每次扩容都是增加oldCapacity >> 1这么多,其实也就是原来容量的一半,不大于就直接放进去OK。
在这里插入图片描述
在这里插入图片描述
具体代码:

		String[] arr = new String[] { "a", "b", "c", "d", "e" };
		ArrayList<String> list = new ArrayList<String>();
		for (String a : arr) {
			list.add(a);
		}
		System.out.println(list);

1.3 利用Collections.addAll(Collection<? super T> c, T... elements)方法,这个其实与第二种一样,只不过把循环过程封装到方法里面了。

具体代码:

		String[] arr = new String[] { "a", "b", "c", "d", "e" };
		ArrayList<String> list = new ArrayList<String>();
		Collections.addAll(list, arr);
		System.out.println(list);

2.array 转 set

2.1 将数组转成list,然后再将list转成set:
hashset的内部其实是用hashmap实现的,set的元素也就是map中的键值,然后map中的value共用了一个new Object()对象(下面的0.75是填装因子,不知道可以去百度)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
具体代码:

		String[] str = new String[] { "a", "b", "c", "a" };
		Set<String> set = new HashSet<String>(Arrays.asList(str));
		System.out.println(set);

2.2 最直接的方法使用循环:

具体代码:

		String[] str = new String[] { "a", "b", "c", "a" };
		Set<String> set = new HashSet<String>();
		for (String s : str) {
			set.add(s);
		}
		System.out.println(set);

2.3 使用Collections.addAll(Collection<? super T> c, T... elements)方法:这个方法内部其实是用for循环实现的,就2.2的方式。

具体代码:

		String[] str = new String[] { "a", "b", "c", "a" };
		Set<String> set = new HashSet<String>();
		Collections.addAll(set, str);
		System.out.println(set);

3.list 转 array

3.1 利用循环语句添加,简单直接。

具体代码:

		List<Integer> ls = new ArrayList<>();
		ls.add(1);
		ls.add(2);
		ls.add(3);
		ls.add(4);
		ls.add(5);
		// 初始化需要得到的数组
		Integer[] array = new Integer[ls.size()];
		// 使用for循环得到数组
		for (int i = 0; i < ls.size(); i++) {
			array[i] = ls.get(i);
		}
		System.out.println(Arrays.toString(array));

3.2 使用Collection接口的toArray()<T> T[] toArray(T[] a)方法:
不带参数的toArray方法,是构造的一个Object数组,然后进行数据拷贝,此时进行转型就会产生ClassCastException,而带参数的toArray方法,则是根据参数数组的类型,构造了一个对应类型的,长度跟ArrayList的size一致的空数组,虽然方法本身还是以 Object数组的形式返回结果,不过由于构造数组使用的ComponentType跟需要转型的ComponentType一致,就不会产生转型异常。

编译不报错,运行时会报ClassCastException错误:

		ArrayList<Integer> ls = new ArrayList<>();
		ls.add(1);
		ls.add(2);
		ls.add(3);
		ls.add(4);
		ls.add(5);
		//构造一个object类型的数组,长度等于ArrayList的size,toArray方法内部就是这么实现的
		//将object类型转为integer类型会报错
		Integer[] array = (Integer[]) ls.toArray();
		System.out.println(Arrays.toString(array));

正确的使用方法:

		ArrayList<Integer> ls = new ArrayList<>();
		ls.add(1);
		ls.add(2);
		ls.add(3);
		ls.add(4);
		ls.add(5);
		// 构造一个Integer类型的数组,长度等于ArrayList的size,toArray内部会用Integer.class
		Integer[] arr = (Integer[]) ls.toArray(new Integer[] {});
		// 或者也OK
		// Integer[] arr = (Integer[]) ls.toArray(new Integer[ls.size()]);
		System.out.println(Arrays.toString(arr));

4.list 转 set

4.1 使用Set接口实现类的构造方法:
值得注意的是:在每个Set接口实现类的内部,都是利用与之对应的Map接口实现类完成的,比如:HashSet的内部是HashMap等。

		String[] arr = new String[] { "b", "c", "a", "d", "e" };
		List<String> list = Arrays.asList(arr);
		// HashSet是不保证插入顺序和自然顺序的,如果下面结果是自然顺序,
		//只是一种概率较大的巧合(由散列值计算方式导致)
		Set<String> set = new HashSet<String>(list);
		System.out.print(set);

4.2 使用Collection接口中声明的addAll(Collection<? extends E> c)方法:

		String[] arr = new String[] { "b", "c", "a", "d", "e" };
		List<String> list = Arrays.asList(arr);
		// HashSet是不保证插入顺序和自然顺序的,如果下面结果是自然顺序,
		// 只是一种概率较大的巧合(由散列值计算方式导致)
		Set<String> set = new HashSet<String>();
		set.addAll(list);
		System.out.print(set);

4.3 使用循环的方法:知道可以这么做就行了,一般不会这么用。

		String[] arr = new String[] { "b", "c", "a", "d", "e" };
		List<String> list = Arrays.asList(arr);
		Set<String> set = new HashSet<String>();
		for (String str : list) {
			set.add(str);
		}
		System.out.print(set);

5.list 转 map

/**
 * @author 作者:ILove996
 * @version 创建时间:2020年3月31日 下午8:31:25 类说明
 */
public class Student {
	public String id;
	public String name;

	public Student(String id, String name) {
		this.id = id;
		this.name = name;
	}
}
		List<Student> list = new ArrayList<Student>();
		list.add(new Student("111", "一号种子"));
		list.add(new Student("222", "二号种子"));
		list.add(new Student("333", "三号种子"));
		{
			/*
			 * 第一种方式: 使用stream流
			 */
			Map<String, Student> map = list.stream().collect(Collectors.toMap(e -> e.id, e -> e));
			System.out.println(map);

			// 当使用stream流添加的key值存在重复的值的时候,使用上面那种操作会报错,这时候就可以像下面这样
			// 简单地添加一个BinaryOperator方法到toMap()中,这也称为合并功能,如果重复,可以取第一个元素
			list.add(new Student("111", "重复一号种子"));// 添加的重复键值
			Map<String, Student> map1 = list.stream()
					.collect(Collectors.toMap(e -> e.id, e -> e, (e1, e2) -> e1));
			System.out.println(map1);

			// 如果想要使用TreeMap对键进行自然排序,或者指定的Map实现呢?如:LinkedHashMap
			Map<String, Student> map2 = list.stream().collect(
					Collectors.toMap(e -> e.id, e -> e, (e1, e2) -> e1, TreeMap<String, Student>::new));
			System.out.println(map2);

			// 如果你的TreeMap实现需要加入比较器,将上面代码中TreeMap<Integer, String>::new替换成:
			// () -> new TreeMap<Integer, String>(new MyComparator())
		}

		{
			/*
			 * 第二种方式: 使用for循环
			 */
			Map<String, Student> forMap = new HashMap<String, Student>();
			for (Student stu : list) {
				forMap.put(stu.id, stu);
			}
			System.out.println(forMap);
		}

6.set 转 list

6.1 使用ArrayList的构造方法ArrayList(Collection<? extends E> c)LinkedList同理:

		Set<String> set = new HashSet<String>();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		List<String> list = new ArrayList<String>(set);
		System.out.println(list);

6.2 使用Collection接口中定义的,被各个实现类重写的 addAll(Collection<?> c) 方法:

		Set<String> set = new HashSet<String>();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		List<String> list = new ArrayList<String>();
		//这个方法内部使用for循环实现的
		list.addAll(set);
		System.out.println(list);

6.3 使用循环语句:

		Set<String> set = new HashSet<String>();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		List<String> list = new ArrayList<String>();
		for (String str : set) {
			list.add(str);
		}
		System.out.println(list);

7.map 转 list

		Map<String, String> map = new HashMap<String, String>();
		map.put("111", "aaa");
		map.put("222", "bbb");
		map.put("333", "ccc");

		// 将Map Key 转化为List
		List<String> mapKeyList = new ArrayList<String>(map.keySet());
		System.out.println(mapKeyList);

		// 将Map values 转化为List
		List<String> mapValuesList = new ArrayList<String>(map.values());
		System.out.println(mapValuesList);

8.map 转 set

		Map<String, String> map = new HashMap<String, String>();
		map.put("111", "aaa");
		map.put("222", "bbb");
		map.put("333", "ccc");

		// 将Map Key 转化为set
		Set<String> keySet = map.keySet();
		System.out.println(keySet);

		// 将Map values 转化为set
		HashSet<String> valueSet = new HashSet<String>(map.values());
		System.out.println(valueSet);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章