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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章