黑马程序员-Java语言基础– 集合框架 第14天

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


集合框架

集合类(java.util.Collection<E>)

为什么出现集合类?

      面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

 

数组和集合类同是容器,有何不同?

      数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

 

集合类的特点

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

 

为什么会出现这么多容器呢?因为每一个容器对数据的存储方式都有不同。这个存储方式称为数据结构。

Collection结构

           |--List

                 |--ArrayList

                 |--LinkedList

                 |--Vector

           |--Set

                 |--HashSet

                 |--TreeSet

Map

      |--Hashtable

      |--HashMap

      |--TreeMap

 

Collection集合共性方法:

      boolean add(E e);//添加元素。addAll();添加一组元素。接收任意类型的对象。

      int size();//获取个数,集合长度。

      boolean remove();//移除元素。

      void clear();//清空容器 al.clear();

      boolean contains();//包含指定元素。

      boolean isEmpty();

      booleanretainAll(Collection<?> c);//仅保留Collection中那些包含在指定collection的元素(可选操作)。即取交集。

      booleanremoveAll(Collection<?> c);//与retainAll作用相反

al1.retainAll(al2);//取交集,al1中只会保留和al2中相同的元素。

al1.removeAll(al2);//去掉相同的元素。al1-->al1:[java01, java02]             

 

1、add方法中的参数类型是Object。以便接收任意类型的对象。

2、集合中存储的都是对象的引用(地址)。集合中不可能存放对象实体。

 

集合取出元素的方式:[day14-03]

      把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式定义成了内部类。而每一个容器的数据结构不同,所有取出的动作细节也不一样。但是都有共性内容:判断和取出。那么可以将这些共性抽取。

      那么这些内部类都符合以规则,该规则就是Iterator。如何获取集合的取出对象呢?通过一个对外提供的方法:iterator();

迭代器(Iterator)

Iterator<E> iterator();//获取迭代器,用于取出集合中的元素。

Iterator中的方法:

      boolean hasNext();

      E next();

      void remove();

什么是迭代器?其实就是集合取出元素的方式。因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。Iterator it = al.iterator();

 

用法:

1.

for(Iterator it = I.iterator();it.hasNext();)

{

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

}//此方法优化了内存使用。使用完毕释放it

 

2.

Iterator it = I.iterator();//循环完毕后it仍然在内存中。

while(it.hasNext())

{

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

}

 

Iterator的设计原理:

      把取出方式定义在集合内部,这样取出方式就可以直接访问集合内部的元素,所以取出方式被定义为内部类。

      而每一个容器的数据结果不同,所以取出的动作细节也不一样,但是都有共性内容:判断和取出。那么就可以将共性抽取成为规则,这些内部类都符合次规则,即Iterator,再通过对外提供的iterator()方法获取集合的取出对象。

 

迭代注意事项:

·迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举) 。

·迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。

·迭代器的next方法返回值类型是Object,所以要记得类型转换。

·在迭代时,循环中next()调用一次,就要hasNext()判断一次。

 

 

集合框架中的常用接口:

Collection接口有两个子接口:List(列表),Set(集)。

      List:可存放重复元素,元素存取是有序的(怎么存进去,怎么取出来)。因为该集合体系有索引。

      Set:不可以存放重复元素,元素存取是无序的(存入和取出的顺序不一定一致)。

 

取出List集合中元素的方式:

·get(int index):通过脚标获取元素。

·iterator():通过迭代方法获取迭代器对象。

 

特有方法:凡是可以操作角标的方法都是该体系特有的方法。

1、增

      add(index,element);

      addAll(index,Collection);

2、删

      remove(index);

3、改

      set(index,element);

4、查

      get(index)

      subList(from,to);

      listIterator();

 

List集合的特有迭代器:ListIterator<E>列表迭代器,是Iterator的子接口。

在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常:

ConcurrentModificationException异常。

所以,在迭代时,只能用迭代器的方式操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出、删除的操作,

如果想要其他的操作,如添加、修改等,就需要使用其子接口ListIterator,该接口只能通过List集合的listIterator方法获取。

ListIterator的方法:(增删改查)

      void add(E e);

      boolean hasNext();

      boolean hasPrevious();//有没有前一个元素。

      E previous();

      void set(E e);

 

List接口中常见的三个子类对象:

ArrayList:线程不安全,查询速度快,增删稍慢。底层数据结构使用数组结构。

LinkedList:链表结构,增删速度快,查询稍慢。底层数据结构使用链表数据结构。

Vector:线程安全(同步),但速度慢,已被ArrayList替代。底层数据结构使用数组。

 

Vector:

Enumeration<E> elements();返回此向量的组件的枚举。

Enumeration是一个接口,类似迭代器,方法有:hasMoreElements();nextElement();

枚举就是Vector特有的取出方式,因名称过长而被迭代器取代。

 

LinkedList:特有方法

addFirst(); addLast();//添加元素。

 

getFirst(); getLast();

获取元素但不删除元素。如果集合中没有元素,会出现NoSuchElementException。

removeFirst(); removeLast();

获取元素,但元素被删除。如果集合中没有元素,会出现NoSuchElementException。

 

在JDK1.6出现了替代方法

offerFirst(); offerLast();//添加元素。

peekFirst(); peekLast();

获取元素,但不删除元素。如果集合中没有元素,会返回null。

pollFirst(); pollLast();

获取元素,但元素被删除。如果集合中没有元素,会返回null。

 

堆栈:先进后出,类似杯子。

队列:先进先出,类似水管。(First in First out FIFO)

 

/*
使用LinkedList模拟一个堆栈或者队列数据结构。

堆栈:先进后出,后进先出。如同一个杯子。
队列:先进先出。First in First out FIFO 如同一个水管。
*/


import java.util.*;
class DuiLie
{
	private LinkedList link;
	DuiLie()
	{
		link = new LinkedList();
	}

	public void myAdd(Object obj)
	{
		link.addFirst(obj);
	}


	public Object myGet()
	{
		return link.removeLast();
	}

	public boolean isNull()
	{
		return link.isEmpty();
	}
}

class  LinkedListTest
{
	public static void main(String[] args) 
	{
		DuiLie dl =  new DuiLie();


		dl.myAdd("java01");
		dl.myAdd("java02");
		dl.myAdd("java03");
		dl.myAdd("java04");
		
		while(!dl.isNull())
		{
			System.out.println(dl.myGet());
		}
	}
}

·List集合判断元素是否相同,依据的是元素的equals()方法。

remove()和 contains()都是使用的equals();[day14-11]

在迭代中,循环中next调用一次,就要hasNext()判断一次。[day14-10]

 

ArrayList()使用频率较高。

ArrayList()判断元素是否相同,采用equals();

HashSet()判断元素存在,唯一性等,依赖的是hashcode和equals方法。

 

Set

|--Set:元素是无序的(存入和取出的顺序不一定一致,元素不可以重复)

常见子类:HashSet和TreeSet。

Set集合的功能和Collection是一致的。

   |--HashSet:底层数据结构是哈希表。线程是非同步的。

           HashSet是如何保证元素唯一性的呢?

           是通过元素的两个方法,hashCode和equals来完成。

           如果元素的HashCode值相同,才会判断equals是否为true;

           如果元素的hashcode值不同,才会调用equals。

 

      注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。

          

   |--TreeSet:可以对Set集合中的元素进行排序。(按照自然顺序)底层数据结构是二叉树。保证数据唯一性的依据:compareTo方法return 0。

     

 

Set集合元素唯一性原因:

1、HashSet:通过equals方法和hashCode方法来保证元素的唯一性。

      如果元素的HashCode值相同,才会判断equals是否为true;如果元素的HashCode值不同,不会调用equals。开发时一般都会复写这两个方法。

注意:对于判断元素是否存在(contains()),以及删除操作(remove()),依赖的方法是元素的hashCode和equals方法。

2、TreeSet:通过compareTo或者compare方法来保证元素的唯一性。元素是以二叉树的形式存放的。

 

·boolean add(obj);//为什么返回布尔型?存进去了返回true,没存进去返回false。

·implements Comparable//该接口强制让自定义对象具备比较性。

·排序时,当主要条件相同时,一定要判断一下次要条件。

 

TreeSet排序的两种方式:[day15-03]

1、让元素自身具备比较性。元素需要实现Comparable接口,覆盖其compareTo方法,这种方式也成为元素的自然顺序,或者叫做默认顺序。

2、当元素自身不具备比较性时,或者具备的比较性不是所需要的时,就需要让集合自身具备比较性,在集合初始化时就拥有比较方式,可以定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

      当两种方式都存在时,以比较器为主。定义一个类,实现Comparator接口,覆盖compare方法。

      字符串本身具备比较性(字母顺序)。


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

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值