[JAVA基础] 十、单双列集合Collection与Map详解

Collection(单列集合顶层接口)

一、Collection接口

1、集合与数组的特点

      集合:a、长度可变;b、只能储存引用数据类型;c、同一个集合中可以存储多种数据类型

      数组:a、长度不可变;b、可以存储基本数据类型和引用数据类型;c、同一个数组只能存储一种数据类型。

2、集合的体系结构图

     a、单例集合体系图

    ---(顶层)Collection(接口)

                    ---List(接口)  

                             ---ArrayList(集合:底层基于可变长数组,查询速度快但增删元素慢,线程不安全,效率高)

                             ---Vector(底层使用数组数据结构,线程安全,效率低,被ArrayList取代)

                              ---LinkList( 底层使用链表数据结构,特点增删快,查询稍慢,线程不安全,效率高)

扫描二维码关注公众号,回复: 2802437 查看本文章

                   ---set(接口)

                               ---HashSet(集合,底层数据结构是哈希表表,线程是非同步的,存取速度快。)

                                ---TreeSet(集合,底层是二叉树数据结构,会对元素进行排序存储)

3、Collection接口中的功能概述

      a、添加元素

            boolean add( Object obj );//添加一个元素

            boolean addAll( Collection c )//一个集合的所有元素

      b、删除元素

           void clear( );//清空集合

           boolean remove ( Object obj )//删除集合中的指定元素

           boolean removeAll( Collection c)//从集合中删除一个指定的集合元素

      c、判断功能

boolean isEmpty ( );//判断集合是否为空

boolean contains( Object obj );//判断集合是否包含指定的元素

boolean containsAll( Collection c );//判断集合中是否存在指定的一个集合中的元素

      d、遍历集合

Iterator iterator( ); //就是获取集合中的每个元素,别名迭代器。

4. 集合的使用步骤

A:创建集合对象

B:创建元素对象

C:向集合中添加数据add()

D:遍历集合

    1 通过集合对象获取迭代器对象iterator()//注当获取到集合的最后一个元素,他又继续获取元素就会报出异常                             NoSuchElementException。

     2 通过hasNext()方法进行判断指针后是否有下一个元素

     3 通过next()方法获取到指针后的下一个元素

e、长度功能

     int size( );//获取集合的长度

f、交集功能

    boolean retainAll( Collection c );//仅保留此 collection 中那些也包含在指定 collection c 的元素。

二、Collection接口的子接口List

一、list接口特点:

1、   元素是有序的,元素可以重复,因为该集合体系有索引。有序:元素读取的顺序与添加顺序一致

2、List接口的特有功能

      a、添加功能

           void add(  int index,Object obj);//向集合指定位置添加元素

      b、删除功能

           Object remove( int index );//删除集合中指定所引出的元素,返回被删除的元素值。

      c、修改功能

           Object set( int index ,Object obj );//用指定的元素替换指定索引位置的值返回被替换的元素值。

      d、获取功能

            Object get( int index );//获取集合指定索引处的值。

            int indexOf( Object obj );//获取指定元素在集合中的第一次出现的索引。

            ListIterator  listIterator( );//列表迭代器

      e、截取功能

            List subList(  int formIndex, int toIndex);//获取集合从指定位置开始到指定位置结束,返回截取出来的集合。

3、并发修改异常的产生和解决方案//遍历集合时,改变了集合的元素

     a:并发修改时怎样产生的呢?

     当我们通过迭代器迭代元素的过程中,又通过集合添加了元素。这种情况是不允许的。因为迭代器是依赖于集合存在           的,如果集合发生了改变,迭代器也应该相应的发生改变。而现在迭代器没有改变,但集合发生了改变,所以报出了并       发修改异常。

     b:解决方案

      注意问题:通过迭代器遍历集合的时候,是不能通过集合去操作(添加、删除),只能使用迭代器的一些操作方法。

    1、全部通过迭代器操作,

    代码: 

     ListIterator lit = list.listIterator();

            while ( lit.hasNext()) {

                String s = (String) lit.next();

                 if ( "hello".equals( s)) {

                      lit.add("IOS");//全部通过迭代器操作:元素是添加到刚遍历的那个元素后面。

                }

           }

    2、全部通过集合操作:

    代码:

    for ( int x = 0; x < list.size(); x++) {

                String s = (String) list.get( x);

                 if ( "hello".equals( s)) {

                      list.add("IOS");//元素是添加到最后的。

                }

           }

二、ArrayList概述

 ArrayList是List接口的一个实现类,在它内部封装了一个长度可变的数组对象。其大部分的方法是从其父类中继承过来的。

三、Vector集合的方法已经被ArrayList方法所取代了。(了解即可)

Vector的特有功能:

* A:添加功能

*           public void addElement(Object obj)       --     add(Object obj)

* B:获取功能

*           public Object elementAt(int index)        --     get(int index)

*           public Enumeration elements()              --     Iterator

*                     boolean hasMoreElements()        --     hasNext()

*                     Object nextElement()                  --  next()

* C:长度功能 

*           public int size()

四、LinkedList

1、概述:LinkedList集合内部维护了一个双向循环链表,链表中的每个元素都使用引用的方式来记住它的前一个元素和后一个元素,从而可以将所有元素彼此连接起来。

2、特有方法

     A:添加元素 

        void addFirst(Object obj );//向集合的开始位置添加元素。

        void addLast( Object obj )//向集合的末尾位置添加元素。

     B: 获取功能

         Object getFirst();//获取集合中的第一个元素

         Object getLast();//获取集合中最后一个元素

    C:删除功能

         Object removeFirst();//删除集合中第一个元素

         Object removeLast();//删除集合中最后一个元素

三、Collection接口的另一个子接口set

一Set接口简介

Set接口继承自Collection接口,它与Collection接口中的方法基本一致,没有对Collection接口进行功能上扩充,但Set接口中的元素是无序的,并且都会以某种规则保证存入的元素不重复出现。

二、Set接口有两个实现类

分别是:HashSet和TreeSet。

其中:HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。

          TreeSet则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。

三、HashSet集合

1、当向HashSet集合中添加元素时,首先会调用该对象的hashCode()方法来确定元素的存储位置,然后再调用对象的equals()方法来确保该位置没有重复元素。——存储原理,保证Set集合中元素没有重复。

2、Set集合和List集合存取元素的方式一样,存add(),取采用迭代器或增强for循环。

3、当向集合中存入元素时,为了保证HashSet正常工作,要求在存入对象时,重写该类中的hashCode()和equals()方法。

复写: hashCode()方法

public int hashCode()

     return this.id;//根据实际比较的成员变量来写
  }

     

复写:equals(Object obj)方法

public boolean equals(Object obj) {

     //可能需要先将Object对象强转成你要添加的元素变量类型

    Student s = (Student)  obj;

    return this.id - s.id;

  }

四、TreeSet集合

1、TreeSet集合中没有重复的元素,并且可以对元素进行排序

2、那么,Treeset是如何存储数据的呢?(基于红黑树,即二叉树)

     A:把第一个存储进去的数据作为根节点

     B:把数据依次和根节点进行比较

           比较得到正数往右放

           比较得到负数向左放

           如果比较得到相等的数,把后来的数据扔掉

    从二叉树结构中取数据的内存规则     

          原则:从每个节点的左边开始,遵循原则  左 中 右  (前序遍历)

3、TreeSet保证元素排序有两种方式: 很重要

    A:自然排序 让对象所属的类去实现Comparable接口。并重写接口中的compareTo方法。

          public int compareTo( Studetn s )  {

            //需求是比较年龄

             int num = this.age - s.age ;

              //当某一个相同的时候,你还需要判断其他的是不是也是相同的。

              int num2 = ( num == 0 ) ? ( this.name.compareTo( s.name ) ) : num ;

              return num2;

        }

        按照年龄从小到大排序     this.age - s.age ;

        按照年龄从大到小排序    s.age - this.age;

     B:比较器接口 Comparator。带参构造。(匿名内部类)

          定义一个MyComparator类实现Comparator接口,并在compare()方法中实现元素的比较,这就相当于定义了一个比较器。

  class MyComparator  implements Comparator<Student>{

     

         public  int compare(Student s1,Student s2){

           

                  int num = s1.getName().length() -  s2.getName().length();

           

                  int num1 = ( num == 0) ? (s1.getName().compareTo( s2.getName())) : num;

           

                  int num2 = ( num1 == 0) ? ( s1.getAge() - s2.getAge()) : num1;

           

                return num2 ;

        }

 }

在内部类中实现比较器:

TreeSet<Student>  ts = new TreeSet<Student>( new Comparator<Student>() {               

 @Override
  public  int compare(Student s1, Student s2) {          
  int num = s1.getName().length() - s2.getName().length();             
  int num1 = ( num == 0) ? (s1.getName().compareTo( s2.getName())): num;              
  int num2 = ( num1 == 0) ? ( s1.getAge() - s2.getAge()) : num1;                 
  return num2;

         }

  } );


Map接口(双列集合的顶层接口)

1、Map接口概述

      Map接口是存储双列集合,键值成对出现且,一 一对应,键的值必须唯一,值可以重复。

2、Map功能概述

     A:增加功能。

          V put(K key, V value)     

                  向集合中添加键值对

                  如果该键存在,则返回被替换的值,新值会添加进去

                  如果该键不存在则直接添加返回null

    B:删除功能。

         void clear()    

                  清空集合中所有数据

         V remove( Object key )    

                   根据键删除键值对元素

    C:判断功能。

          boolean containsKey( Object key )    

                    判断集合中是否包含指定的键

          boolean containsValue( Object value )

                    判断集合中是否包含指定的值

          boolean isEmpty()

                   判断集合是否为空 

     D:获取功能。

           Set<Map.Entry<K,V>> entrySet()    最好用的键值对迭代方法

                   获取键值对儿对象的集合

          Object get( Object key )

                  根据键获取值

           Set<K> keySet():

                  获取集合中所有键的Set集合

           Collection<V> values()    

                 获取集合中所有值的集合

      E:长度功能。

            int size()

                  获取集合的长度

3、Map三个子实现类

      A: HashMap:底层是哈希表数据结构,允许使用null键和null值,该集合是不同步的。

      B:   Hashtable: 底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步的,已被HashMap取代。

      C: TreeMap:底层是二叉树结构,不允许null键(因为是该集合根据键来排序存储),线程不同步,可以用于给Map                                  集合中的键进行排序,和set集合很像,set集合底层就是使用了Map集合。                 

4、Map集合中元素的两种取出方式

     a: Set<K>     keySet()方法,将map集合中所有的键存入到set集合中,因为set集合具有迭代器,所以可以用迭代                的方法,取出所有的键(增强for(){ }循环),再根据 Object get(Object key)方法,获取每个键所对应的值,

    b:Set<Map.Entry<K,V>> entrySet() 方法,将map集合中的映射关系存入到set集合中,而这个关系的数据类型就是                 Map.Entry<K,V>,然后使用增强for(){ }循环遍历,再使用Map.Entry<K,V>接口的getKey()和getValue()方法           获取键和值。

5、HashMap和TreeMap集合

    a:HashMap集合存储自定义对象做键,要重写hashCode()方法和equals()方法,因为如果用自定义对象当做键的话,要             保持元素的唯一性(因为键是唯一的),根据实际要求,使用自定义对象的某些属性作为键值的比较。

    b:TreeMap集合存储自定义对象做键,要做一下操作:

          实现排序方式一:让对象所属的类去实现Comparable接口,重写compareTo方法

          实现排序方式二:用TreeMap的带参构造,在参数位置接收 Comparator接口对象.

6、HashMap和Hashtable的区别

     A:HashMap     线程不安全,效率高.允许键和值为null. JDK1.2

     B:Hashtable线程安全,效率低,不允许键和值为null。JDK1.0

猜你喜欢

转载自blog.csdn.net/bilibili_/article/details/81665411