JAVA第十五弹《Collection(一)》

来源:互联网 发布:知乎 暴利 编辑:程序博客网 时间:2024/06/06 02:20

----------------------android培训、java培训、期待与您交流! ----------------------

                                                    JAVA第十五弹《Collection(一)》

                     ——————(个人见解,有错误的地方欢迎批评指正)—————

                                                              (如有雷同纯属巧合)

程序中经常遇到有收集对象的需求,之前收集对象的方式是用Object数组,但是用数组收集对象在操作上有一定得局限性,Java SE中提供了满足各种需求的的API,而针对对象收集,Java提供了Collection API,先看看其接口继承架构:

收集对象的共同行为定义在Collection中,然而收集对象会有不同的需求。如果希望收集时记录每个对象的索引顺序,并根据索引取回对象,这样的行为定义在List中;如果希望收集的对象不能出现重复,则定义在Set中;如果收集的对象希望用队列的方式,先收集的对象后取,后存的对象先取,则可以用Queue;而如果希望可以对Queue的两端进行存储或取出,则可以用Deque

看看下例:

import java.util.*;public class ArrayListDemo1 {public static void main(String[] args) {List list = new ArrayList();list.add(1);list.add(3);list.add(2);list.add(7);list.add(5);list.remove(3);System.out.println("集合元素的个数:"+list.size());Collections.sort(list);System.out.println(list.get(3));System.out.println(list);}}


上述程序输出结果为:

集合元素的个数:4

5

[1, 2, 3, 5]

上面的例子中,ArrayList收集了5Integer对象,然后移除了下标为3的元素,这时候集合里面剩下4个元素,然后再进行从小到大的排序。上例是把集合中的元素全部打印出来了,那么如何逐个取出集合中的元素呢?看看下例:

import java.util.*;public class ArrayListDemo1 {public static void main(String[] args) {List list = new ArrayList();list.add(1);list.add(3);list.add(2);list.add(7);list.add(5);Iterator it = list.iterator();while(it.hasNext()){System.out.println(it.next());}}}


上述程序输出结果为:1,3,2,7,5

iterator()(也叫迭代器)会返回Iterator接口的操作对象,这个对象包括了Collection收集的所有对象,可以使用IteratorhasNext()判断有无下一个对象,若有的话返回true,则可以使用next()取得下一个对象。因此,无论是List,Set,Queue还是任何Collection都可以使用Iterator进行迭代。

(注意:在循环中每次用next()取得下一个对象后,都应该用hasNext()判断一次是否还有下一个对象。)

现在要收集一个Student类的对象,如下:

class Student {private String name;private int age;private String ID;Student(String name,int age,String ID){this.name = name;this.age = age;this.ID = ID;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getID() {return ID;}public void setID(String iD) {ID = iD;}}


建立测试类:

import java.util.*;public class ArrayListDemo2 {public static void main(String[] args) {List array = new ArrayList();array.add(new Student("zhangsan",20,"A001"));array.add(new Student("lisi",18,"A002"));array.add(new Student("wangwu",16,"A003"));Collections.sort(array);}}


运行上述程序将会报错:

这是因为是根本没告诉sort()方法到底是对Student的name、age、还是ID进行排序,Collections的stor()方法要求被排序的对象,必须操作java.lang.Comparable接口,这个接口有个compareTo()方法必须返回大于0、小于0或等于的数,接下来要对上述的例子的年龄进行排序,如下:

class Student implements Comparable{private String name;private int age;private String ID;Student(String name,int age,String ID){this.name = name;this.age = age;this.ID = ID;}public int compareTo(Object obj){Student stu = (Student)obj;return this.age - stu.age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getID() {return ID;}public void setID(String iD) {ID = iD;}}


import java.util.*;public class ArrayListDemo2 {public static void main(String[] args) {List array = new ArrayList();array.add(new Student("zhangsan",20,"A001"));array.add(new Student("lisi",18,"A002"));array.add(new Student("wangwu",16,"A003"));Collections.sort(array);Iterator it = array.iterator();while(it.hasNext()){Student stu = (Student)it.next();System.out.println("姓名:"+stu.getName()  +" 年龄:"+stu.getAge()+" 学号:"+stu.getID());}}}


程序执行结果为:

姓名:wangwu 年龄:16 学号:A003

姓名:lisi 年龄:18 学号:A002

姓名:zhangsan 年龄:20 学号:A001

上面是通过Student实现Comparable接口进行比价,但是有时候我们得不到Student的原始码,或者不能修改Student类,那么还有另外一种方式:

class StudentComparator implements Comparator{public int compare(Object obj1,Object obj2){Student stu1 = (Student)obj1;Student stu2 = (Student)obj2;return stu1.getAge()-stu2.getAge();}}import java.util.*;public class ArrayListDemo3 {public static void main(String[] args) {List array = new ArrayList();array.add(new Student("zhangsan",20,"A001"));array.add(new Student("lisi",18,"A002"));array.add(new Student("wangwu",16,"A003"));Collections.sort(array,new StudentComparator());Iterator it = array.iterator();while(it.hasNext()){Student stu = (Student)it.next();System.out.println("姓名:"+stu.getName()  +" 年龄:"+stu.getAge()+" 学号:"+stu.getID());}}}


上述程序执行结果:

姓名:wangwu 年龄:16 学号:A003

姓名:lisi 年龄:18 学号:A002

姓名:zhangsan 年龄:20 学号:A001

上述代码使用了Collectionsore()方法的另外一个重载版本,可以接受操作Comparator接口的对象,如果使用这个版本,排序方式将根据Comparatorcompare()定义来决定。

现在改一改需求,要求不能在上述收集Student对象的ArrayList中出现重复元素(姓名,年龄,学号相同)。代码如下:

class Student {private String name;private int age;private String ID;Student(String name,int age,String ID){this.name = name;this.age = age;this.ID = ID;}public boolean equals(Object obj){if(!(obj instanceof Student))throw new RuntimeException("存入了非Student对象");Student stu = (Student)obj;if(this.ID.equals(stu.ID))return true;return false;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getID() {return ID;}public void setID(String iD) {ID = iD;}}public class ArrayListDemo {public static void main(String[] args) {ArrayList array = new ArrayList();array.add(new Student("zhangsan",20,"A001"));array.add(new Student("lisi",18,"A002"));array.add(new Student("wangwu",16,"A003"));array.add(new Student("zhangsan",20,"A001"));array = soleElement(array);Iterator it = array.iterator();while(it.hasNext()){Student stu = (Student)it.next();System.out.println("姓名:"+stu.getName()   +" 年龄:"+stu.getAge()+" 学号:"+stu.getID());}}public static ArrayList soleElement(ArrayList list){ArrayList newList = new ArrayList();Iterator it = list.iterator();while(it.hasNext()){Object obj = it.next();if(!newList.contains(obj))newList.add(obj);}return newList;}}


程序输出结果为:

姓名:zhangsan 年龄:20 学号:A001

姓名:lisi 年龄:18 学号:A002

姓名:wangwu 年龄:16 学号:A003

上述程序实现了删除重复元素的功能,原理就是新创建了个ArrayList,然后把原ArrayList的元素逐个进行比较,把不重复的元素存到新的ArrayList中,最后把新的ArrayList的实例给原ArrayList参考。用contains进行比较调用的Object中的equals(),所以Student类中覆盖了Object中的equals方法。

数组在内存中会是连续的线性空间,根据索引随机存取时速度快,如果操作上有这类需求时(比如排序)就可以使用ArrayList,有较好的速度表现。假如使用LinkedList,那么根据链表数据结构的特性,想要知道索引存取对象时,链表方式都得使用从第一个元素开始查找下一个元素的方式,排序时,刚好必须将索引01000的元素调换,效率肯定就不行了。而如果需要调整索引顺序时,速度的表现就不尽人意,比如,在已经收集100个对象的ArrayList中,使用可指定索引的add()方法,将对象新增到索引0位置,那么原先索引0的对象必须调整至索引1的位置,索引1的对象必须调整到索引2的位置……以此类推,使用ArrayList并不经济。而这时候用LinkedList,链表的结构中每个元素会参考下一个元素,这有利于调整索引的顺序,若已收集100个对象,操作可指定索引的方法,将对象新增到索引0的位置,很大程度上提高了效率。

 

----------------------android培训、java培训、期待与您交流! ----------------------