A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Duang__ 中级黑马   /  2015-11-29 22:06  /  725 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

集合框架一

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去重复问题:

[html] view plaincopy
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

一道面试题:

[html] view plaincopy
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 个回复

您需要登录后才可以回帖 登录 | 加入黑马