集合與數組互轉
一.集合轉數組
以ArrayList集合為例,使用該集合的一個成員方法toArray(),可以將一個集合對象轉化為一個數組。如下所示:
1 void listToArray(){ 2 List<String> list=new ArrayList<>();//創建一個集合對象 3 list.add("a");//向集合對象裏添加元素 4 list.add("b"); 5 list.add("c"); 6 System.out.println("原集合:"+list);//打印集合 7 Object[] array = list.toArray();//集合轉數組 8 System.out.println("集合轉數組後:"+Arrays.toString(array));//打印數組 9 }
上述代碼打印結果:
原集合:[a, b, c]
集合轉數組後:[a, b, c]
二.數組轉集合
對於數組轉集合,類Arrays給我們提供了一個方法asList(),可以生成一個“集合”,我們看一下生成的該集合有什麽特點:
1 Object[] listToArray1(){ 2 List<String> list=new ArrayList<>();//創建一個集合對象 3 list.add("a");//向集合對象裏添加元素 4 list.add("b"); 5 list.add("c"); 6 return list.toArray();//集合轉數組 7 } 8 void arrayToList1(){ 9 Object[] array = listToArray1(); 10 List<Object> asList = Arrays.asList(array); 11 System.out.println("數組轉假集合:"+asList); 12 /** 13 * 註意: 14 * 我們通過查看Java API源代碼可以知道,15 * Arrays.asList(T... a)產生的集合,並非真正意義上的集合,Arrays.asList()方法返回的是類Arrays的一個私有靜態內部類,並非真正意義上的集合體系, 16 * 實際上仍然是一個數組,我們可將該集合稱為"假集合" 17 * 該"假集合"可以像數組一樣對元素進行遍歷查詢, 18 * 但是不能像真正的集合那樣對元素進行增刪改,否則會報錯 19 */ 20 }
既然Arrays.asList(T... a)產生的是“假集合”,那麽如何通過數組轉化成一個真正的集合呢?我們可以在“假集合”的基礎上,產生一個“真集合”:
1 void arrayToList2(){ 2 Object[] array = listToArray1(); 3 List<Object> asList = Arrays.asList(array);//假集合 4 ArrayList<Object> list = new ArrayList<>(asList);//假集合轉真集合 5 System.out.println("集合中原來的元素:"+list); 6 list.add("d"); 7 list.add("e"); 8 System.out.println("向集合中添加兩個元素後:"+list); 9 list.remove(1); 10 System.out.println("刪除集合中角標為1的元素後:"+list); 11 list.set(0,"哈哈"); 12 System.out.println("修改集合中角標為0的元素後:"+list); 13 }
上述代碼打印後的結果如下:
集合中原來的元素:[a, b, c]
向集合中添加兩個元素後:[a, b, c, d, e]
刪除集合中角標為1的元素後:[a, c, d, e]
修改集合中角標為0的元素後:[哈哈, c, d, e]
三.集合中元素的排序問題
我們先來看一個對集合中元素進行重新排序的案例:
1 void sortList(){ 2 List<String> list=new ArrayList<>(); 3 list.add("張三"); 4 list.add("李四"); 5 list.add("王五"); 6 list.add("趙六"); 7 list.add("田七"); 8 list.add("劉八"); 9 list.add("孫九"); 10 System.out.println("排序前,默認按照元素插入的先後順序進行排序:"); 11 for (int i=0;i<list.size();i++){ 12 System.out.print(list.get(i)+" "); 13 } 14 System.out.println(); 15 /* 16 類Collections為我們提供了一個sort()方法,該方法傳入了兩個參數, 17 一個是待排序的集合對象, 18 另一個是實現了接口Comparator的類的實例 19 */ 20 Collections.sort(list, Collator.getInstance(java.util.Locale.CHINA)); 21 /** 22 * 註意: 23 * 這是根據的漢字的拼音的字母排序的,而不是根據漢字一般的排序方法 24 */ 25 System.out.println("排序後,按照指定的排序規則進行排序:"); 26 for (int i=0;i<list.size();i++){ 27 System.out.print(list.get(i)+" "); 28 } 29 }
上述代碼運行後結果如下:
排序前,默認按照元素插入的先後順序進行排序:
張三 李四 王五 趙六 田七 劉八 孫九
排序後,按照指定的排序規則進行排序:
李四 劉八 孫九 田七 王五 張三 趙六
通過上述案例可以看出,我們對集合中的元素進行排序,實際上在內部采用了對比較器接口的重新定義。
一般來說,我們常用的比較器接口主要有兩個,一個是接口Comparator,另一個是接口Comparable。我們查看這兩個接口用於元素比較的核心方法如下:
public interface Comparator<T> { int compare(T o1, T o2);//用於比較傳入的兩個參數的大小 boolean equals(Object obj);//用於比較是否相等 } public interface Comparable<T> { public int compareTo(T o);//用指定對象與傳入的參數比較大小 }
上述兩個比較器接口中,我們主要來看用於比較大小的方法。在對兩個對象元素進行比較時,返回1表示前面的元素比後面的元素大,返回0表示兩個元素相等,返回-1表示前面的元素比後面的元素小。我們知道,集合裏可以儲存任意對象,接下來,我們在集合裏儲存自定義的對象,然後對這些對象元素進行排序。
我們先用接口Comparable,重寫裏面的compareTo()方法,具體如下:
1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.List; 4 public class Test3 { 5 //定義一個學生A內部類,令其實現接口Comparable,重寫裏面的comparaTo()方法 6 static class StudentA implements Comparable{ 7 private String name; 8 private int age; 9 public StudentA() { 10 } 11 public StudentA(String name, int age) { 12 this.name = name; 13 this.age = age; 14 } 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 public int getAge() { 22 return age; 23 } 24 public void setAge(int age) { 25 this.age = age; 26 } 27 @Override 28 public String toString() { 29 return "StudentA{" + 30 "name=‘" + name + ‘\‘‘ + 31 ", age=" + age + 32 ‘}‘; 33 } 34 //比較年齡大小 35 @Override 36 public int compareTo(Object o) { 37 StudentA otherStu= (StudentA) o; 38 int otherStuAge = otherStu.getAge(); 39 return this.getAge()>otherStuAge?1:this.getAge()<otherStuAge?-1:0; 40 } 41 } 42 public static void main(String[] args) { 43 List<StudentA> list=new ArrayList<>(); 44 StudentA stuA1 = new StudentA("小明", 17); 45 StudentA stuA2 = new StudentA("小光", 15); 46 StudentA stuA3 = new StudentA("小光", 16); 47 StudentA stuA4 = new StudentA("小光", 14); 48 StudentA stuA5 = new StudentA("小光", 18); 49 list.add(stuA1); 50 list.add(stuA2); 51 list.add(stuA3); 52 list.add(stuA4); 53 list.add(stuA5); 54 System.out.println("排序前,默認排序:"); 55 for (int i=0;i<list.size();i++){ 56 System.out.println(list.get(i)); 57 } 58 Collections.sort(list); 59 System.out.println("按照StudentA的age升序排列:"); 60 for (int i=0;i<list.size();i++){ 61 System.out.println(list.get(i)); 62 } 63 Collections.reverse(list); 64 System.out.println("按照StudentA的age降序序排列:"); 65 for (int i=0;i<list.size();i++){ 66 System.out.println(list.get(i)); 67 } 68 } 69 }
接下來,我們再通過接口Comparator實現自定義排序。在使用該方法時,我們需要寫一個比較器類來實現接口Comparator,並重寫裏面的compare(Object o1, Object o2)方法。具體如下:
1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Comparator; 4 import java.util.List; 5 public class Test4 { 6 static class StudentB{ 7 private String name; 8 private int age; 9 public StudentB() { 10 } 11 public StudentB(String name, int age) { 12 this.name = name; 13 this.age = age; 14 } 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public int getAge() { 23 return age; 24 } 25 public void setAge(int age) { 26 this.age = age; 27 } 28 @Override 29 public String toString() { 30 return "StudentB{" + 31 "name=‘" + name + ‘\‘‘ + 32 ", age=" + age + 33 ‘}‘; 34 } 35 } 36 static class MyComparator implements Comparator { 37 38 @Override 39 public int compare(Object o1, Object o2) { 40 StudentB stuB1= (StudentB) o1; 41 StudentB stuB2= (StudentB) o2; 42 return stuB1.getAge()>stuB2.getAge()?1:stuB1.getAge()<stuB2.getAge()?-1:0; 43 } 44 } 45 public static void main(String[] args) { 46 List<StudentB> list=new ArrayList<>(); 47 StudentB stuB1 = new StudentB("小明", 17); 48 StudentB stuB2 = new StudentB("小光", 15); 49 StudentB stuB3 = new StudentB("小光", 16); 50 StudentB stuB4 = new StudentB("小光", 14); 51 StudentB stuB5 = new StudentB("小光", 18); 52 list.add(stuB1); 53 list.add(stuB2); 54 list.add(stuB3); 55 list.add(stuB4); 56 list.add(stuB5); 57 System.out.println("排序前,默認排序:"); 58 for (int i=0;i<list.size();i++){ 59 System.out.println(list.get(i)); 60 } 61 //創建自定義的比較器對象 62 MyComparator mc=new MyComparator(); 63 Collections.sort(list,mc); 64 System.out.println("按照StudentB的age升序排列:"); 65 for (int i=0;i<list.size();i++){ 66 System.out.println(list.get(i)); 67 } 68 Collections.reverse(list); 69 System.out.println("按照StudentB的age降序序排列:"); 70 for (int i=0;i<list.size();i++){ 71 System.out.println(list.get(i)); 72 } 73 } 74 }
上述代碼運行後的結果如下:
排序前,默認排序: StudentB{name=‘小明‘, age=17} StudentB{name=‘小光‘, age=15} StudentB{name=‘小光‘, age=16} StudentB{name=‘小光‘, age=14} StudentB{name=‘小光‘, age=18} 按照StudentB的age升序排列: StudentB{name=‘小光‘, age=14} StudentB{name=‘小光‘, age=15} StudentB{name=‘小光‘, age=16} StudentB{name=‘小明‘, age=17} StudentB{name=‘小光‘, age=18} 按照StudentB的age降序序排列: StudentB{name=‘小光‘, age=18} StudentB{name=‘小明‘, age=17} StudentB{name=‘小光‘, age=16} StudentB{name=‘小光‘, age=15} StudentB{name=‘小光‘, age=14}
最後,使用比較器不僅可以比較兩個元素的大小,從而實現自定義排序,還可以運用於集合中元素的查重。 在對集合中的元素進行查重時,我們通常還要配合對象的toString()方法,以及hashCode()和equals()方法進行。
集合與數組互轉