黑马程序员-集合框架之Collection

来源:互联网 发布:爱德华大夫观后感 知乎 编辑:程序博客网 时间:2024/05/21 14:10

集合(Collection)

定义:用于存储对象的可变长度的容器。

对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定。

就使用集合容器进行存储。

 

集合特点:

1,用于存储对象的容器。

2,集合的长度是可变的。

3,集合中不可以存储基本数据类型值。

数组的特点:

1、只能存储单一类型的对象。2、数组的大小一旦规定不能再改变。

集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。集合中常用类的继承关系如下:

Collection:该接口中定义了集合的共性方法。如下:

1,添加。

booleanadd(Object obj):

booleanaddAll(Collection coll):

2,删除。

booleanremove(object obj):

booleanremoveAll(Collection coll);

voidclear();

3,判断:

booleancontains(object obj)

booleancontainsAll(Colllectioncoll);

boolean isEmpty():判断集合中是否有元素。

 

4,获取:

Int size():获取容器大小。

Iterator iterator():取出元素的方式:迭代器。

5,其他:

booleanretainAll(Collection coll);取交集。

Object[]toArray():将集合转成数组。

 

演示代码如下:

 

迭代器:Iterator

所有 Collection 集合共性的取出方式。

迭代器的由来:每一个容器都应该有取出功能。这些功能定义都是一样,因为每个容器的数据结构不一样,这些功能实现的具体方式也不同。这些实现方式应该在容器类的内部,在类的内部对对类中的数据进行操作更方便。取出功能的实现比较复杂,因而将它定义为一个容器的内部类,这些内部类。每个容器的定义取出功能的内部类都有相同的部分,将其抽取出来,就形成了Iterator接口。

而每一个容器都在其内部对该接口进行了内部类的实现。

也就是将取出方式的细节进行封装。通过iterator方法对外提供了一个取出元素的对象。

在使用时,通常通过两个方法来完成。

1,判断容器中是否有元素hasNext()方法。2,取出元素next()方法。需要取出所有元素时,可以通过循环,java建议使用for循环。因为可以对内存进行一下优化。

注意:在迭代时,next方法每调用一次,内部指针就会自定往下走。在循环,next方法调用一次即可,否则会出现想不到的结果。

注意:在迭代过程中,不能使用集合中的方法来操作集合中的元素。会发生并发修改异常(CurrentModificationException)。因此,Iterator具有很大的局限性。

例如:for(Iterator it =c.iterator();it.hasNext();;)

            {

                    Objectobj  = it.next();

                    if(obj.equals(ddd)

                        c.add(sdkj);//此举就会导致并发修改异常。

                }

 

Collection 的子类特点

Collection

|--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

|--Set:元素不能重复,无序。

List:特有的常见方法:有一个共性特点就是都可以操作角标。

1,添加

voidadd(index,element);

voidadd(index,collection);

2,删除;

Objectremove(index):

3,修改:

Objectset(index,element);

4,获取:

Objectget(index);

int indexOf(object);

int lastIndexOf(object);

ListsubList(from,to);

5list集合支持列表迭代器ListIterator

Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。

对于 Iterator 的子接口ListIterator在迭代list集合时,还可以对元素进行添加

(add(obj)),修改set(obj)的操作。listIterator可以在遍历过程中实现对集合元素的曾删改查。

listIterator的方法如下:

 

void

add(E e)
            将指定的元素插入列表(可选操作)。

 boolean

hasNext()
            以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。

 boolean

hasPrevious()
            如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。

 E

next()
            返回列表中的下一个元素。

 int

nextIndex()
            返回对 next 的后续调用所返回元素的索引。

 E

previous()
            返回列表中的前一个元素。

 int

previousIndex()
            返回对 previous 的后续调用所返回元素的索引。

 void

remove()
            从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。

 void

set(E e)
            用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。

 

List

特点:元素有序,集合中的元素可以重复,因为有索引。

List特有的方法:

有一个共性特点就是都可以操作角标。

1,添加

voidadd(int index,E element);

voidadd(int index,collection c);

2,删除;

Objectremove(int index):

3,修改:

Objectset(int index,E element);

4,获取:

Objectget(int index);

int indexOf(object);

int lastIndexOf(object);

ListsubList(int from,int to);包含头不包含尾

子类特点:

ArrayList:用数组实现,线程不同步。查询速度快,增删速度稍慢。

LinkedList:链表实现,线程不同步,查询速度慢,增删速度快。

Vector:数组实现,线程同步。效率低,一般不使用。

LinkedList

特有方法:

addFirst();  offerFirst();

 

addLast():   offetLast();

 

getFirst();.//获取但不移除,如果链表为空,抛出NoSuchElementException.

peekFirst();//获取但不移除,如果链表为空,返回null.

 

getLast();

peekLast():

 

removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException.

pollFirst();//获取并移除,如果链表为空,返回null.

 

removeLast();

pollLast();

Set

Set:元素不可以重复,是无序。

Set接口中的方法和Collection一致。

|--HashSet:内部数据结构是哈希表,是不同步的。

保证该集合的元素唯一性:

通过hashCode()和equals()方法来完成对象唯一性的。

如果哈希值不同,那么不用equals()方法判断是否是同一个对象,就直接存储到哈希表中。

如果哈希值相同,那么要再次判断对象的equals方法是否为true。

如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

记住:如果元素要存储到HashSet集合中,必须覆盖hashCode()方法和equals()方法。

注意:覆盖public int hashCode()和booleanequals(Object object)一定要要与父类的方法相同,否则不是覆盖,而是重新定义了一个新函数。

 

|--TreeSet:可以对Set集合中的元素进行排序。是不同步的。

判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。

TreeSet对元素进行排序的方式一:

让元素自身具备比较功能,元就需要实现Comparable接口。覆盖compareTo()方法。

如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?

可以使用TreeSet集合第二种排序方式二:

让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare()方法。

将该类对象作为参数传递给TreeSet集合的构造函数。

方法代码演示:

1、自定义Person类使其具有比较性

 

 

2、自定义比较器,可以在集合建立时指定比较器

 

 

泛型

1、 java升级的好处:高效、简化书写,安全。

jdk1.5出现的安全机制。优点:(1)将运行错误ClassCastException转化为编译问题,提高安全性。(2)避免了强制转换的麻烦。

泛型的应用:通过<>来定义操作的引用型数据的类型。常用于集合中,指定集合要操作的元素的类型。

1、 泛型可以作用于类上。例如:

class Util<T> {

     private T t;

     public setObject(T t)

{

    this.t =t;

            }

     public getObject(T t)

        {

            return t;

}

}

泛型类定义的泛型在整个类中有效,泛型类的对象明确要操作的类型后,整个类中所有方法要操作的类型都确定了。

2、 泛型可以定义在方法上。如果定义方法时不知道方法要操作的类型,可以使用泛型。例如:

public <T> String  getInfo(T t)

{

     Return t;

}

同一个类中不同的方法定义不同的泛型,可以让同类中的方法操作不同类型。

注意:静态方法不可以访问定义在类上的泛型。因为静态优先于类存在。

3、 泛型可以定义在接口上,由实现它的类指定要操作的数据类型。例如:

interface Inter<T>

{

   void show(T t);

}

class InterImleimplements Inter<String>

{

   publicvoid show(String t)

   {

      System.out.println(t);

   }

}

4、泛型的限定。

(1) <? super类名>表示要操作的类型是指定的类或者其父类

<?Extends 类名>表示要操作的类型是自定的类或者其子类。

 

原创粉丝点击