您的位置:首页 > 其它

集合

2015-08-01 15:49 309 查看
集合

1、集合和数组

     1、集合概述
          由于我们使用的是面向对象语言,所以,我们要经常使用对象。而很多时候,我们可能需要使用很的对象,这个时候,我们就只能使用以前讲过的数组进行存储了,而数组的特点是长度固定。这样的话就不适合变化的数据。所以,java重新提供了一种容器,用于存储对象,这种容器叫集合
     2、集合和数组的区别

数组:

数组长度固定。
数组可以存储基本数据类型,也可以存储引用类型。
数组存储的数据类型是一致的。

集合:

集合长度可变。
集合只能存储引用类型。
集合可以存储不同类型的对象

     总结:集合比数组强大,类似于包装类和基本类型的关系

2、集合体系结构

Collection                          (接口)
     |——List                       (接口)
          |——ArrayList         (类)
          |——Vector            (类)
          |——LinkedList       (类)
     |——Set                      (接口)
          |——HashSet         (类)
          |——TreeSet          (类)

集合框架图:



3、Collection接口中成员方法

添加
boolean add(Object obj)

向集合中添加一个元素(常用)

boolean addAll(Collection c)

向集合中添加一个集合的元素

删除
void clear()

删除集合中的所有元素

boolean remove(Object obj)

从集合中删除指定的元素(常用)

boolean removeAll(Collection c)

从集合中删除一个指定的集合元素

判断
boolean isEmpty()

判断集合是否为空

boolean contains(Object obj)

判断集合中是否存在指定的元素(常用)

boolean containsAll(Collection c)

判断集合中是否存在指定的一个集合中的元素

遍历
Iterator iterator()

就是用来获取集合中每一个元素(常用)

长度
int size()

获取集合中的元素个数(常用)

交集
boolean retainAll(Collection c)

判断两个集合中是否有相同的元素

把集合转换成数组
Object[] toArray()

把集合转换成数组(常用)

4、List接口

1、特点
     元素有序可重复,可以通过索引值操作对应位置的元素, 而Set中的元素是无序唯一的
2、成员方法

添加
void add(int index, Object obj)

在指定位置添加元素(常用)

删除
Object remove(int index)

根据指定索引删除元素,并把删除的元素返回(常用)

修改
Object set(int index, Object obj)

把指定索引位置的元素修改为指定的值,返回修改前的值(常用)

获取
int indexOf(Object o)

返回指定元素在集合中第一次出现的索引(常用)

Object get(int index)

返回指定索引位置对应的元素(常用)

ListIterator listIterator()

列表迭代器

截取
List subList(int fromIndex, int toIndex)

截取集合

 

5、迭代器

1、迭代的概念
     按照某种方式重复的做事情
2、迭代器Iterator
    主要遍历Collection集合中的元素,迭代是取出集合中元素的一种方式

3、原理
     于多种集合的数据结构不同,所以存储方式不同,所以,取出方式也不同。这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可。
     迭代器是一个内部类,在集合的内部定义了一个类,这个类实现了Iterator接口
4、使用
          List list = new ArrayList();

          list.add(1);

          list.add(3);

          Iterator iterator = list.iterator();

          while(iterator.hasNext()){

               Integer next = (Integer)iterator.next();

               System.out.println(next);

           }
5、常见问题
     ConcurrentModificationException:在迭代的时候给集合增加元素,删除元素(注意:不是通过索引删除)造成的
     并发修改异常:在next()方法第一行进行判断,如果预期的修改次数(expectedModCount)和实际的修改次数(modCount)不同就会发生此异常
6、Iterator 和 ListIterator的区别
     1、Iterator是ListIterator的父接口
     2、Iterator是Collection集合的公共的取出容器中元素的方式,对于List,Set都通用。而ListIterator是List集合的特有的取出元素的方式
     3、Iterator中只具备hasNext(),next(),remove()方法,可以删除被遍历到的元素
          ListIterator中具备对遍历到的元素进行增(add)删(remove)改(set)查(next)的方法,可以对元素逆向遍历previouse相对于next,hasPreviouse相对于hasNext(用的很少)
7、成员方法

Iterator 
boolean hasNext()

若被迭代的集合元素还没有被遍历,返回 true

Object next()

返回集合的下一个元素

void remove()

删除集合上一次 next()方法返回的元素。 (若集合中有多个相同的元素, 都可以删掉)

ListIterator  继承自Iterator
void add(Object obj)

将指定元素插入next()方法返回的元素后面

void set(Object obj)

用指定元素替换next()或previouse()方法返回的元素

boolean hasPrevious()

若被迭代的集合元素还没有被遍历,返回 true

Object previous()

返回集合的上一个元素

6、集合的遍历

1、集合的遍历方式

1、迭代
2、将集合转换为数组
3、获取集合的长度,通过get(索引)+for遍历

          4、使用for高级循环
               for(Object obj : list){
                    System.out.println(obj);
               }
2、for循环遍历和迭代器遍历的区别
          1、最主要的区别就是remove方法,想要在循环的过程中删除元素就要用迭代器,因为迭代器的remove方法不仅会删除元  素,还会维护一个标志,用了记录当前状态是不是可删除。而for循环脚标是变化的,删除元素会报错,因为list.size()大小发      生变化了
          2、ArrayList里面维护的是数组,顺序结构,所以用get方法获取比较快,因而用for循环
               LinkedList里面维护的是链表,链式结构,Iterator中的next()方法,采用的即是顺序访问的方法,因此用迭代器比较快

7、集合体系

Collection                          (接口)

     |——List                       (接口) 元素有序,可以重复

          |——ArrayList          (类)

          |——Vector             (类)

          |——LinkedList        (类)

     |——Set                       (接口) 元素无序,唯一

          |——HashSet           (类)

          |——TreeSet            (类)

8、数据结构

1、栈
     特点:先进后出
2、队列
     特点:先进先出
3、数组
     特点:查询快,增删慢
4、链表
     特点:查询慢,增删快

9、List接口的三个子类的特点

1、ArrayList
      底层数据结构是数组,查询快,增删慢
      线程不安全,效率高。
2、Vector
      底层数据结构是数组,查询快,增删慢
      线程安全,效率低。
3、LinkedList
      底层数据结构是链表,查询慢,增删快
      线程不安全,效率高。
4、什么时候使用?
       查询多用ArrayList,增删多用LinkedList

10、Vector类

     底层数据结构是数组,查询快,增删慢

     线程安全,效率低。

[align=center]Vector 成员方法[/align]
[align=justify]public void addElement(Object obj)[/align]
[align=justify]添加[/align]
[align=justify]public Object elementAt(int index)[/align]
[align=justify]获取[/align]
[align=justify]public Enumeration elements()[/align]
[align=justify]获取[/align]
[align=justify]public int size()[/align]
[align=justify]长度[/align]
  

11、LinkedList类

  1、特点

底层数据结构是链表,查询慢,增删快
线程不安全,效率高。

[align=center]LinkedList 成员方法[/align]
[align=justify]void addFirst(Object o)[/align]
[align=justify]添加[/align]
[align=justify]void addLast(Object o)[/align]
[align=justify]Objcet getFirst()[/align]
[align=justify]获取[/align]
[align=justify]Object getLast()[/align]
[align=justify]Object removeFirst()[/align]
[align=justify]删除[/align]
[align=justify]Object removeLast()[/align]
  

12、ArrayList类

1、特点     
     底层数据结构是链表,查询慢,增删快

     线程不安全,效率高。
     为了简化Vector中的方法名而存在的
2、如何存储不重复的自定义对象
     重写自定义对象的equals()方法
     

13、泛型

1、概述
     泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型
     泛型就相当于一个预定义类型
2、好处
     A、解决了黄色警告线问题
     B、把系统运行期间的异常提前到了编译期间
     C、优化了程序设计,不需要做强制转换了
3、不足
     泛型传入的只能是引用类型
4、泛型的定义
     A、在类上定义
          //在类上定义一个泛型
          public class MyArrayList<T> {

          }
           //在类上定义两个泛型
          public class MyArrayList<T, S> {

          }          
          //在类上定义两个泛型,且第二个类型必须是第一个类型的子类
          public class MyArrayList<T, S extends T> {

          }

          说明:
               T,S是名字,可以随意起,该处定义的泛型可以在本类的任意地方使用
               父类上定义的泛型不能被子类继承

      B、在方法上定义
          //在方法上定义一个泛型
          public <M> void show(M m){
          }
          //在方法上定义两个泛型
          public <M, S> void show(M m, S s){
          }
           //在方法上定义两个泛型,且第二个泛型必须事第一个泛型的子类
          public <M, S extends M> void show(M m, S s){
          }
          说明:
               T,S是名字,可以随意起,该处定义的泛型可以在该方法的任意地方使用
     C、在接口上定义泛型
         和在类上定义一样
3、泛型的使用
     可以在继承关系,实现关系,创建对象时使用
     在使用过程中,父类或父接口如果没有明确给定类型,那么子类必须定义泛型而且需要和父类或父接口的泛型名字一样

14、增强for循环

1、格式
     for(数组 或 Collection子类 的元素类型 变量名 :数组 或 Collection子类)
     {
          //使用变量
     }
2、好处
     方便数组和集合的遍历
3、注意事项
     增强for是用来代替Iterator的
     不要再遍历的时候用集合对集合本身进行修改
4、集合遍历的四种方式
     1、迭代
     2、将集合转换为数组(忘记吧)
     3、获取集合的长度,通过get()+for遍历
     4、使用for高级循环
               for(Object obj : list){
                    System.out.println(obj);
               }

15、遍历方式

1、迭代器(Set中只有iterator()方法)
2、增强for
3、将转换成数组

16、HashSet类

1、哈希值概念
     哈希值:哈希值就是调用对象的hashCode()方法后返回的一个int型数字
     哈希桶:简单点理解就是存储相同哈希值对象的一个容器
2、HashSet类中的add(obj)方法如何保证元素的唯一性
     重写hashCode()和equals()方法 ,为什么,如果一个对象的哈希值和eques方法与容器中的对象有相同的,就不添加。如果没有就添加
3、开发中如何编写hashCode()和equals()方法
     通过eclipse自动生成即可

17、TreeSet类

1、如何保证元素唯一性
     内部采用的是二叉树结构,相同的元素就不操作
2、如何判断两个元素是否相同

A、对象所属的类去实现Comparable接口

重写compareTo方法

如果该方法返回0 ,则两个元素相同
public class Person implements Comparable{

               @Override

               public int compareTo(Object o) {

                    return 0;

               }

}

TreeSet set = new TreeSet();

set.add(new Person());
B、调用TreeSet的带参构造方法,传入Comparator的子类对象
该子类对象重写compare(T o1, T o2)方法
如果返回0则两个元素相同
public class MyComparator implements Comparator {

     @Override

     public int compare(Object o1, Object o2) {

          return 0;

     }

}

TreeSet set = new TreeSet(new MyComparator());

set.add(new Student);
3、排序
     A、对象所属的类去实现Comparable接口,重写compareTo方法
     B、调用TreeSet的带参构造方法,传入Comparator的子类对象,该子类对象重写compare方法

18、Collections类

排序          :     public static void sort(List list)
查找          :     public static binarySearch(List list, Object obj)
反转          :     public static void reverse
最大值       :     public static Object max(Collection coll)
随机换位    :     public static void shuffle(List list)

19、Collection集合总结

[align=center]Collection( 接口)单列集合[/align]
[align=center]List( 接口)[/align]
[align=center]有序,不唯一[/align]
[align=center]Set( 接口)[/align]
[align=center]可能无序,肯定唯一[/align]
[align=center]Vector( 类)[/align]
[align=center]ArrayList( 类)[/align]
[align=center]LinkecList( 类)[/align]
[align=center]HashSet(类)[/align]
[align=center]TreeSet(类)[/align]
1、底层数据结构是数组,查询快,增删慢
[align=justify]
[/align]
[align=justify]2、线程安全,效率低(只有Vector是线程安全的)[/align]
1、底层数据结构是数组,查询快,增删慢
[align=justify]
[/align]
[align=justify]2、线程不安全,效率高[/align]
1、底层数据结构是链表,增删快,查询慢
[align=justify]
[/align]
[align=justify]2、线程不安全,效率高[/align]
1、底层数据结构是哈希表
[align=justify]
[/align]
[align=justify]2、通过重写hashCode() 和equals() 保证唯一性[/align]
[align=justify]
[/align]
[align=justify]
[/align]
[align=justify]3、线程不安全,效率高[/align]
[align=justify]
[/align]
[align=justify](如果元素相同不操作,所以不会覆盖)[/align]
[align=justify]1、底层数据结构是二叉树[/align]
[align=justify]
[/align]
[align=justify]2、通过判断compareTo或compare 方法的返回值是否为 0来判断是否重复[/align]
[align=justify]
[/align]

[align=justify]3、排序有两种方案:[/align]
[align=justify]实现Comparable接口重写 compareTo方法[/align]
[align=justify]实现Comparator接口重写 compare方法[/align]
[align=justify]
[/align]
[align=justify]4、线程不安全,效率高[/align]
[align=justify]
[/align]
[align=justify](如果元素相同不操作,所以不会覆盖)[/align]

  
 

20、Map集合成员方法

增加功能
V put(K key, V value)

当key在集合中不存在时,添加元素;当key在集合存在时候,替换元素

删除功能
void clear

清除所有键值对数据

V remove(Object key)

根据指定的键删除键值对

判断功能
boolean containsKey(Object key)

判断指定的键是否在集合中存在

boolean containsValue(Object value)

判断指定的值是否在集合中存在

boolean isEmpty

判断集合是否为空

获取功能
Set<Map.Entry<K,V>> entrySet()

键值对对象的集合

Object get(Object key)

根据键获取值

Set<K> keySet():

所有键的集合

Collection<V> values()

所有值的集合

长度
int size()

获取长度

 

 

21、Map集合的两种遍历方式

创建

Map集合

// 创建集合对象
              Map<String, String> map = new HashMap<String,
String>();
 
              // 创建并添加元素
              map.put("杨过", "小龙女");
              map.put("郭靖", "黄蓉");
              map.put("梁山伯", "祝英台");
              map.put("牛郎", "织女");

第一种

遍历方式(通过keySet())

              Set<String> keySet = map.keySet();
              for(String
key : keySet){
                     System.out.println("key:"+key+"
 value"+map.get(key));
              }

第二种

遍历方式(通过entrySet())

              Set<Entry<String,String>> entrySet = map.entrySet();
              for(Map.Entry<String,
String> entry : entrySet){
                   System.out.println("key"+entry.getKey()+"
 value"+entry.getValue());
              }

22、集合体系-总结

注意:只有Vector和HashTable是线程安全的,效率低。

Collection(单列集合)Map(双列集合)
          |--Collection(单列)

               |--List(有序,可重复)

                    |--ArrayList

                         底层数据结构是数组,查询快,增删慢。

                         线程不安全,效率高。

                    |--Vector

                         底层数据结构是数组,查询快,增删慢。

                         线程安全,效率低。

                    |--LinkedList    


                         底层数据结构是链表,查询慢,增删快。

                         线程不安全,效率高。

               |--Set(可能无序,肯定唯一)

                    |--HashSet

                         底层数据结构是哈希表。

                         线程不安全,效率高。

                         怎么保证唯一性的呢?

                         它依赖两个方法:hashCode()和equals()

                         顺序:

                              首先判断hashCode()值是否相同。

                              同:继续走equals(),看返回值

                                   如果true:就不添加到集合。

                                   如果false:就添加到集合。

                              不同:就添加到集合。

                    |--TreeSet

                         底层数据结构是二叉树。

                         线程不安全,效率高。

                         怎么保证唯一性的呢?是根据返回是否是0。

                         怎么保证排序的呢?两种方式

                              自然排序(元素具备比较性)

                                   实现Comparable接口

                              比较器排序(集合具备比较性)

                                   实现Comparator接口
          |--Map(双列 底层结构是针对键有效,跟值无关)

               |--HashMap

                    底层数据结构是哈希表。

                    线程不安全,效率高。允许null键和值

                    怎么保证唯一性的呢?

                    它依赖两个方法:hashCode()和equals()

                    顺序:

                         首先判断hashCode()值是否相同。

                         同:继续走equals(),看返回值

                              如果true:就不添加到集合。

                              如果false:就添加到集合。

                         不同:就添加到集合。

               |--Hashtable

                    底层数据结构是哈希表。

                    线程安全,效率低。不允许null键和值

                    怎么保证唯一性的呢?

                    它依赖两个方法:hashCode()和equals()

                    顺序:

                         首先判断hashCode()值是否相同。

                         同:继续走equals(),看返回值

                              如果true:就不添加到集合。

                              如果false:就添加到集合。

                         不同:就添加到集合。

               |--TreeMap

                    底层数据结构是二叉树。

                    线程不安全,效率高。

                    怎么保证唯一性的呢?是根据返回是否是0。

                    怎么保证排序的呢?两种方式

                         自然排序(元素具备比较性)

                              实现Comparable接口

                         比较器排序(集合具备比较性)

                              实现Comparator接口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: