一.集合转数组
以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}
最后,使用比较器不仅可以比较两个元素的大小,从而实现自定义排序。
此外,我们还可以在集合中对元素进行查重。此时,我们先通过比较hashCode(),再比较equals(),从而判断集合中的元素是否重复。