Collection集合


一、集合概述:

1、集合特点:

    集合只用于存储对象,集合的长度是可变的,可以存储不同类型的对象。

2、集合和数组的区别?

    1、集合的长度是可变的,数组的长度是固定的。

    2、数组可以存储对象和基本数据类型,集合只能存储对象。

3、集合框架的由来:

    因为集合有很多,而且各个集合的数据结构都有不同,但都具备共性,这些共性通过向上抽取就形成了集合框架。

    数据结构:就是容器中对象的存储方式。

4、迭代器Iterator

    迭代器是集合中元素的取出方式,而每个集合怎么取出元素集合自己清楚,所以迭代器定义在内部类中。只要是Collection集合中的容器,迭代器是通用的取出方式。

publicclass InteratorDemo {

    publicstaticvoid main(String[] args) {

       Collection coll =newArrayList();

       coll.add("java1");

       coll.add("java2");

       coll.add("java3");

       coll.add("java4");

       //获取迭代器,并用迭代器迭代元素。

       for(Iterator it = coll.iterator();it.hasNext();){

           System.out.println(it.next());

       }

    }

}

列表迭代器ListIteator:ListIterator继承了Iterator

    使用Iterator在对集合进行迭代时,在迭代的过程中是不能对集合进行修改的,因为如果对集合进行操作,那么迭代器是不知道的,所以就会产生不确定性。

    如果想要在迭代的过程中想要对元素进行更多的操作,可以使用ListIterator列表迭代器中提供了更多对元素操作的方法。

ListIterator提供了对元素增,删,改,查的方法:

5、注意事项:

    1、集合中真正存储的是对象的引用。

    2、jdk1.5后可以直接存储基本数据类型数据,因为有自动装箱机制。

    3、在开发中一般存储的都是自定义对象。

6、集合使用注意:

    1、用add方法存储时,都被提升为了Objcet。取出时如果要使用自定义对象的特有方法,一定要进行向下转型

    2、一般集合都结合泛型使用,如果定义泛型就可以不用强转了。

 System.out.println((Person)it.next().getName());// 强转过程,点的优先级别很高,所以要用小括号括起来。

    3、在迭代过程,循环中只需要有一个it.next()即可。

二、集合文档。

Collection集合框架图:

Collection中的方法:

1、添加:

boolean add(E e):一次添加一个元素。

boolean addAll(Collection):将一个容器中的元素添加到当前容器中。

2、删除:

boolean remove(Object o):删除一个指定对象。

boolean removeAll(Collection c):删除参数容器和本容器中相同的元素。

void clear():直接将容器中的元素清空。

3、判断:

boolean contains(Object o):是否包含指定元素。

boolean containsAll(Collection c):是否包含指定容器中的元素。容器中元素发生变化为ture

boolean inEmpty():是否有元素,是否为空。

LinkedList中特有操作方法:

addFirst();将指定元素插入此列表的开头。

addLast();将指定元素添加到此列表的结尾。

jdk1.6以后,变成。

offerFirst();

offerLast();

 

getFirst();返回此列表的第一个元素。如果列表为空,抛出异常。

getLast();返回此列表的最后一个元素。如果列表为空,抛出异常。

jdk1.6以后。

peekFirst();返回此列表的第一个元素。如果列表为空,返回null。

peekLast();返回此列表的最后一个元素。如果列表为空,返回null。

 

removeFirst();移除并返回此列表的第一个元素。如果列表为空,抛出异常。

removeLast(); 移除并返回此列表的最后一个元素。如果列表为空,抛出异常。

jdk1.6以后。

pollFirst();移除并返回此列表的第一个元素。如果列表为空,返回null

pollLast();移除并返回此列表的最后一个元素。如果列表为空,返回null

List集合中的方法:基本上和Collection一致,只是多了角标的操作。

    1、添加

    void add(int index,E element):将元素插入指定角标位置。

    boolean addAll(int index,collection c):将参数容器中的元素插入指定位置角标。

    2、删除

    E remove(index);

    3、获取

    获取元素:

    E get(index):根据角标获取元素。

    获取索引:

    int indexOf(object):根据元素获取元素第一次的角标。如果没有元素,返回-1.

    int lastIndexOf(object):根据元素获取元素最后出现的角标。

    获取子列表:

    List subList(fromIndex,toIndex):获取列表中的一部分,包含fromIndex,不包含toIndex。

    4、修改

    object set(index,element):替换指定位置的元素,并返回被替换掉的元素。

我们发现List接口可以对元素进行增,删,改,查的操作(只有这个具备)。

 

|--List:列表。

    特点:

    1、有序(存储元素的顺序和取出元素的顺序相同)。

    2、该集合中的元素都有索引,可以通过索引来访问元素。

    3、该集合可以存储相同元素。

|--Set:集:这个集合中的方法和Collection一致。

    特点:

    1、不能存储重复元素。

    2、存入的元素顺序和取出元素的顺序不一定不同(具体的容器对象数据结构不同,顺序也有不同)。

 

List的常见子类对象:我们重点学的是这些子类对象的特有数据结构,以及相关特点。

 |--vectorjdk1.0就存在了,底层是数组结构的,是可变长度数组 ,vector是同步的。

    可变数组原理:一旦原数组长度不够,会创建新数组,将原数组的元素复制到新数组中,并将新元素添加到新数组中。

    vector有两种取出元素的方式:

    方式一:迭代器。

    方式二:枚举。跟迭代器的取出方式是一样,就是写法不一样,后期枚举被迭代器取代了。

|--ArrayList1.2后出现的,底层是数组结构,也是支持长度可变数组的。好处:查询元素效率很高。

        是不同步的。替代了vector,因为效率高。

|--LinkedList底层是链接列表结构。这种结构的特点是每个元素都会记住后面跟着的元素的位置。       

        这种结构好处:对元素的增删效率非常高。但是查询效率很低。

   

两种常见的数据结构:

    1、队列:先进先出。

    2、堆栈:先进后出。

    面试题:用LinkedList集合模拟队列和堆栈结构。

    定义一个功能,去除ArrayList中重复的元素。使用contains方法判断交集。contains方法依赖equals。

定义一个功能,去除重复ArrayList集合中重复元素,用ArrayList存储自定义Person对象,如果姓名和年龄相同就不存储。

 

Set集合中常见的子类对象:

HashSet

    |--HashSet底层数据结构是哈希表,不保证顺序,是不同步的。

                 1HashSet的特点:

                         1、不关心顺序。

                         2、提高了查询效率。

                         3、不能存储相同元素。

               2HashSet容器中元素存储位置?

将要存储的元素先通过哈希算法算出一个哈希值,来标识存储的位置,代表着元素。想要查找元素,通过元素的哈希算法算出哈希值,再通过哈希值到哈希表中查找。

              3、判断元素唯一性的依据是?

                  判断哈希值,通过hashCode方法来完成。

                  判断元素相同,通过equals方法来完成。ture视为元素相同。

所以使用HashSet集合来存储元素需要覆盖元素的hashCodeequals方法。

覆盖方法代码演示:

覆盖Object类中的hashCode方法,建立Person对象自己特点的哈希算法。HashSet集合。

    publicint hashCode(){

       returnname.hashCode() +age;

    }

覆盖equals方法,建立Person对象自身的比较方法。HashSet集合。

    publicboolean equals(Object obj){

       if(!(objinstanceof Person)){

           returnfalse;

       }

       Person p = (Person)obj;

       returnthis.name.equals(p.name) && this.age == p.age;

    }            

TreeSet    

|--TreeSet底层是二叉树结构。可以给set集合中的元素进行指定顺序排序,默认情况下是通过元素自然顺序排序的。

 

1、保证元素唯一:保证元素元素唯一性的依据是看compareTo方法返回结果是否为0,是0就视为相同,不存。

       注意:TreeSet集合存储的对象必须要具备比较功能,不然会出现异常。

       如何写conpareTo的对象比较:

(重点)覆盖conpareTo方法进行比较的时候,通常,先比较主要条件,如果主要条件相同,再比较次要条件。

    2TreeSet排序方式:

TreeSet排序方式一:让元素自身具备比较性,需要实现Comparable接口,覆盖compareTo方法。

    需求:按照姓名进行排序。姓名主要,年龄次要。

通常,比较的时候,先比较主要条件,如果主要条件相同,再比较次要条件。如果想要按照一个人的年龄排序,如果年龄相同,再比较姓名。

//覆盖compareTo()方法,建立person类的比较方法。

publicint compareTo(Object o) {  

    Person p = (Person)o;

    if(this.age>p.age)

        return 1;

    if(this.age<p.age)

        returnthis.name.compareTo(p.name);//这是String对象中的比较方法。

        //为什么这么调用??? this.name相当于一个字符串对象,所以可以调用方法。

    return -1;

    /*

     * 技巧性写法。

     */

//  Person p = (Person)o;

//  int temp = this.age - p.age;

//  return temp==0?this.name.compareTo(p.name):temp;

}

TreeSet排序方式二:比较器排序方式,让容器自身具备比较性。

如果元素自身具备的比较性(自然顺序)不是所需要的,那就用这种排序方式。容器中有一个构造方法,TreeSet(comparator).可以再容器初始化时,指定一个比较器。

    自定义比较器:需要实现Comparator接口,覆盖Compare方法即可。

需求:对字符串的长度进行排序,使用TreeSet集合。

定义了一个根据PersonName进行比较的比较器。

publicclass ComparatorByNameimplementsComparator {

    publicint compare(Object o1,Object o2){

       Person p1 = (Person)o1;

       Person p2 = (Person)o2;    int temp = p1.getName().compareTo(p2.getName());

       return temp==0?p1.getAge()-p2.getAge():temp;

    }

}

其他容器:

     LinkedHashSet集合中的一个有序集合。

       hashSet查询速度比较快,但不能保证顺序。

       是hashSet的子类:1.4版本后出现LinkedHashSet

       存储元素:还是按照哈希表存,但是会按照链表的方式记录住每个元素。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想飞的鱼20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值