黑马程序员——JavaSE之集合框架一

来源:互联网 发布:淘宝打折工具有什么用 编辑:程序博客网 时间:2024/06/03 02:07

                                          --------Java培训、Android培训、iOS培训、.NET培训期待与您交流-------

                                                           集合框架一

 Collection:是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

 与Collection很容易在一起说的是Collections,java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。




看集合对象的小技巧:

 集合分体系:List Set

 子类对象的后缀名是所属体系,前缀名是数据结构名称。

 List:新出的子类都是以List结尾的,通常都是非同步的。

     |-----ArrayList:看到array,就知道数组,查询速度快。

     |-----LinkedList:看到link,就知道链表,增删速度快。

 

 Set:

     |-----HashSet:看到hash,就知道哈希表,查询速度更快,并想到元素唯一,通过hashCode(),equals方法

     |-----TreeSet:看到tree,就知道二叉树,可以排序,排序想到Comparable-compareTo Comparator--compare方法。


ArrayList,LinkedList

  Collection:

     |----List:有序的,带索引的,通过索引就可以精确的操作集合中的元素,元素时可     以重复的。List提供了增删改查操作。

          增加add(element)  add(index,element)

          删除remove(element)  remove(index)

          修改set(index,element)

          查询get(index)

        |---Vector:可以增长的数组结构。同步的。

|---ArrayList:是数组结构,长度是可变的(创建新数组+复制数组),查询速度很快,增删较慢,不同步的。

|---LinkedList:是链表结构,不同步的,增删速度很快,查询速度较慢。

     可用于实现堆栈,队列。

     堆栈:先进后出First in Last Out FILO

     队列:先进先出 First in First Out FIFO

   List可以存储重复元素的,如果需求中要求容器中的元素必须保证唯一性。

 

     |----Set:不包含重复元素的集合,不保证而且方法和Collection一致。Set集合取出元素的方法只有一种:迭代器。

|--HashSet:哈希表结构,不同步,保证元素唯一性的方式依赖于:hashCode(),equals()方法。查询速度快。

|--TreeSet :可以对Set集合中的元素进行排序。使用的是二叉树结构。

   保证元素唯一性: 使用的对象比较方法的结果是否为0,如果是0就视为相同元素不存。

 


元素的排序比较有两种方式:

  1.元素自身具备自然排序,或者具备的自然排序不是所需要的,这时只能用第二种方式。

  2.比较器排序,其实就是在创建TreeSet集合时,在构造函数中指定具体的比较方式。需要定义一个类实现Comparator接口,重写compare方法。

到此为止:再往集合中存储对象时,通常该对象都需要覆盖hashCode,equals,同时实现Comparale接口,建立对象的自然排序。通常还有一个方法也会复写toString();


利用ArrayList去重复问题:

import java.util.ArrayList;import java.util.Iterator;import java.util.List; public class ArrayListTest {public static void main(String[] args) {List list = new ArrayList(); list.add("itcast1");list.add("itcast2");list.add("itcast1");list.add("itcast2");list.add("itcast1");list.add("itcast2");getSingleElement(list);  //取出重复元素System.out.println(list);}/* * 案例:去除List集合中的重复元素 *  * 思路:1.先创建一个临时容器,用于存储唯一性的元素。 *      2.遍历原容器,将遍历到元素放到临时容器中去判断,是否存在 *      3.如果存在,不存储到临时容器中。如果不存在,不存储到临时容器中。 *      4.遍历结束后,临时容器中国存储的就是唯一性的元素。 *      5.如果需要将这些唯一性的元素保留到原容器清空,将临时容器中等个元素添加到元容器中即可。 *       */public static List getSingleElement(List list){//1.创建一个临时容器List temp = new ArrayList();//2.遍历原容器。for(Iterator it = list.iterator(); it.hasNext();){Object obj = it.next();//对遍历到的每一个元素都到临时容器中去判断是否包含。if(!temp.contains(obj)){  //如果不存在temp.add(obj);}}//唯一性的元素已经被记录到临时容器中,清空原容器中的元素。list.clear();//把临时容器中的元素添加到原容器中。list.addAll(temp);return temp;}}

其中LinkedList常用的方法:addFirst()   addLast()   getFirst()  getLast()  removeFirst()  removeLast()

  可以发现在LinkedList中特有的方法命名:围绕头和尾展开定义的。First  Last

一道面试题:

import java.util.LinkedList; public class LinkedListTest {public static void main(String[] args) {/* * 面试题:用LinkedList模拟一个堆栈或者队列数据结构。 *        创建一个堆栈或者队列数据结构对象。 *///创建一个队列对象Queue queue = new Queue();//往队列中添加元素queue.addQueue("itcast1");queue.addQueue("itcast2");queue.addQueue("itcast3");queue.addQueue("itcast4");while(!queue.isNull()){System.out.println(queue.GetQueue());}}}/***定义一个队列数据结构。Queue*/class Queue{//封装了一个链表数据结构。private LinkedList link;/* * 队列初始化时,对链表对象初始化。 */Queue(){link= new LinkedList();}/* *队列的添加元素的功能  */public void addQueue(Object obj){//内部使用的是链表的方法lin * 判断队列中元素是否为空,没有元素就是真的 */public boolean isNull(){return link.isEmpty();}}k.addFirst(obj);}/* * 队列的获取方法 */public Object GetQueue(){return link.removeLast();}

哈希表

通过对哈希表的分析:存储元素时,先调用了元素对象的hashCode()方法,而每个学生对象都是新建立的对象,所以hashCode值都不相同,也就不需要判断equals了。

 

默认equals比较两者的hashCode

在HashSet对象中查找数据,是根据数据的hashCode进行换算,确定在哪个区域。

如果两个对象equals一样,最后让它们的hashCode也一样,但如果存在ArrayList中,hashCode是没有用处的。

当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet的哈希值就不一样了,这样即使使用该对象的当前引用作为参数检索该对象,也找不到了,这将导致无法从HashSet中单独删掉这个对象,造成内存泄露。


TreeSet篇:

TreeSet的add方法内部最终实现:需要将元素转成Comparable类型。因为这个类型具备排序的能力。这个类型中有一个专门为排序提供了一个compareTo方法。

   如果需要对象有比较排序的功能,需要让对象扩展功能,实现Comparable接口。

   提示:在比较时,必须明确主次。主要条件相同,继续比较次要条件。(这里可以用三目运算符)


在编程中会遇到ConcurrentModificationException异常

ConcurrentModificationException异常:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

引发此异常的原因:在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。

解决思路:在迭代时,不要使用集合的方法操作元素。 此时应该想到Iterator有一个子接口ListIterator可以完成该问题的解决,通过List接口中的listIterator()就可以获取。该列表迭代器只用List接口有。



小知识点补充

  foreach:其实就是增强for循环。

  格式:for(数据类型 变量 : Collection集合or数组){}

  用途: 遍历Collection和数组。通常只能遍历元素,不要再遍历的过程中做对集合元素的操作。

  

  与之前的for循环有什么区别?

   新的for循环必须有被遍历的目标。目标只能是Collection或者是数组。

   建议:遍历数组时,如果仅为遍历,可以使用增强for如果要对数组的元素进行操作,使用老式for循环可以通过角标操作。





0 0