黑马程序员——关于集合(上)

来源:互联网 发布:知乎和天涯哪个真实 编辑:程序博客网 时间:2024/05/18 15:03

----------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------

 

   集合包括Collection &Map,Collection接口定义了集合框架的共性功能,包括List接口类和Set接口类,List中的元素是有序的,元素可以重复,因为该集合体系有索引;Set中的元素是无序的,元素不可以重复。

   在Collection中可以进行增[add(e);addAll(collection);]删[remove(e);removeAll(collection);clear();]查[包括判断、获取等]操作,其中对于集合中数据的获取要使用迭代器。迭代器,其实就是集合的取出元素的方式。迭代器的使用方法如下:

        ArrayList al = new ArrayList();

        Iterator it = al.iterator();

   List是一个接口类,它又包含了以下三个类:

   1、ArrayList类:底层的数据结构使用的是数组结构。线程不同步。特点:查询速度很快,增删稍慢。

   2、LinkedList类:底层使用的是链表数据结构。线程不同步。特点:增删速度很快,查询稍慢。

    3、Vector类:底层是数组数据结构。线程同步,导致速度慢,被ArrayList替代了。

   在List接口类中,有一些特有的方法,除了有了改的方法[set(index,element);],对于“增”、“删”、“查”也可以增加一个角标参数从而实现对特定位置元素的操作。还定义了一个List集合特有的迭代器ListIterator,Iterator的子接口。

    为什么要定义ListIterator呢?

   因为Iterator中提供的方法是有限的,只能对元素进行判断、取出和删除,想要添加、修改只能使用其子接口ListIterator。

 

    ArrayList& LinkedList的性能比较:
    在快速追加和遍历的时候,ArrayList的效率比LinkedList的效率要高
    在对List中的数据结构进行修改时,LinkedList比ArrayList的效率要高

 

   Vector类的取出方式是比较特别的枚举Enumeration,其实它和迭代是一样的,这个后面的java提高会继续学习。

 

Set接口,无序集合。所谓无序,就是指存入和取出的顺序不一定一致。它主要包含两种:

1、HashSet类:底层的数据结构是哈希表,由HashMap实现。不保证set 的迭代顺序,特别是它不保证该顺序恒久不变。

那么怎样排除HashSet中的重复对象呢?通过元素的两个方法,hashCode()和equals()来完成。如果元素的HashCode值相同,才会判断equals是否为true;如果元素的HashCode值不同,那么不会调用equals方法。

2、TreeSet类:底层的数据结构是二叉树,可以实现对Set集合中的元素进行排序,使用compareTo方法排除重复对象和对对象排序。

TreeSet的排序的功能,每放入一个对象都会把传入的对象和Set中的对象进行比较,然后进行排序。(这种方法效率不高,不适用于快速放入对象。)

一般情况可以用HashSet进行重复对象的筛选。如果想进行排序,用HashSet实例重新构造出来一个TreeSet实例。

TreeSet排序有两种方式:

第一种方式是让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法,这种也称为元素的自然顺序,也叫做默认排序。比如:

class Student implementsComparable//该接口强制让学生具备比较性。{

    privateString name;

    private intage;

    Student(Stringname,int age){

      this.name = name;

      this.age = age;

    }

    public intcompareTo(Object obj){  //复写compareTo方法

      if(!(obj instanceof Student))//判断比较的对象是否为Student类

         throw new RuntimeException("不是学生对象");

     Student s = (Student)obj;

     System.out.println(this.name+"....compareto....."+s.name);

     //由此可以看出比较的方式是每个对象与之前所有的对象进行比较

      if(this.age>s.age)

           return 1;//返回1,证明该对象比比较对象次序高。

      if(this.age==s.age){

          return this.name.compareTo(s.name);//如果年龄相同,则比较姓名。

                                            //String类中有覆盖compareTo这个方法

       }

       return -1; //返回-1,证明该对象比比较对象次序低。

    }

    public String getName(){

        return name;

     }

    public int getAge(){

        return age;

    }

}

compareTo方法通过返回值判断前后两个元素的前后顺序。

第二种方式是当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数;定义一个类,实现Comparator接口,覆盖compare方法。比如:

class MyCompare implementsComparator{//定义实现Comparator接口的类

    publicint compare(Object o1,Object o2){//覆盖compare方法

      Student s1 = (Student)o1;

      Student s2 = (Student)o2;

      int num = s1.getName().compareTo(s2.getName());//先比较name是否相同

      if(num==0){

           

          //以上语句可以直接使用下面一句代码代替。拆箱、装箱。

          return new Integer(s1.getAge()).compareTo(newInteger(s2.getAge()));

        }

        return num;

     }

}

当以上两种排序都存在时,以比较器为主。

 

----------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!----------------------

 详细请查看:http://edu.csdn.net

原创粉丝点击