黑马程序员技术交流社区

标题: 集合总结,一位大神的笔记,分享给大家学习下 [打印本页]

作者: Me_Wuhaidon9    时间: 2016-5-27 22:23
标题: 集合总结,一位大神的笔记,分享给大家学习下
##1.集合体系
* 概述:能够存储任意对象,长度可以改变.
* Collection              (接口)
*    |——List              (接口)        有序,有索引,可重复
*         |——ArrayList     (类)
*         |——Vector        (类)
*         |——LinkedList    (类)
*    |——Set               (接口) 无序,无索引,不可重复
*         |——HashSet       (类)
*         |——TreeSet       (类)
* 集合和数组的区别
* 数组:
        * 数组长度固定。
        * 数组可以存储基本数据类型,也可以存储引用类型。
        * 数组存储的数据类型是一致的。
* 集合:
        * 集合长度可变。
        * 集合只能存储引用类型。
        * 集合可以存储不同类型的对象
* 总结:集合比数组强大,类似于包装类和基本类型的关系

##2.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 cotainsAll(Colletion c)        判断集合中是否存在指定的一个集合中的元素
* 遍历
        * Iterator()
* 长度
        * int size()
* 交集
        * boolean retainAll(Collection c)        判断两个集合是否有相同的元素
* 把集合转数组
        * Object[] toArray()
                String[] arr = list.toArray(new String[list.size()]);

##3.List接口
* 1.特点
        * 元素有序可重复,可以通过索引值操作对应位置的元素, 而Set中的元素是无序唯一的

* 2.成员方法(相对Collection主要是多了对索引的操作)
* 添加
        * 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)        截取集合

##4.List接口三子类
* 1.数据结构
        * 栈:先进后出
        * 队列:先进先出
        * 数组:查询快,增删慢
        * 链表:查询慢,曾删快
* 2.三子类特点
* ArrayList:底层数据结构是数组,查询快,增删慢.线程不安全,效率高.
* Vetor:底层数据结构是数组,查询快,增删慢.线程安全,效率低.
* LinkedList:底层数据结构是链表,查询慢,增删快.线程不安全,效率高
        * 添加       
                void addFirst(Object o)
                void addLast(Object o)
        * 获取
                Objcet getFirst()
                Objcet getLast()
        * 删除
                Object removeFirst()
                Object removeLast()
* 什么时候用?        查询多用ArrayList,增删多用LinkedList
* tips:Vetor在写法上类似Iterator,可结合记忆

##5.HashSet
* 1.哈希值概念
        * 哈希值:哈希值就是调用对象的hashCode()方法后返回的一个int型数字
        * 哈希桶:简单点理解就是存储相同哈希值对象的一个容器
* 2.通过重写hashCode() 和equals() 保证唯一性
* 个人理解:
        * 哈希值是通过地址值计算出来的,重写equals是为了比较属性
        1.重写hashCode()让相同属性哈希值相同,从而通过eqauls()判断,从而确实是否存入
        2.优化hashCode是为了使不同属性的对象哈希值尽量不同,从而不走equals
* 3.线程不安全,效率高

##6.TreeSet
* 1.如何保证元素唯一性:内部采用的是二叉树结构,相同的元素就不操作
* 2.排序有两种方案
        * A.对象所属的类去实现Comparable接口,重写compareTo方法.如果该方法返回0,则两个元素相同
*
            public class Person implements Comparable<Person> {
                    @Override
                       public int compareTo(Object o) {
                                int num = this.name.compareTo(o.name);
                            return num == 0 ? this.age - o.age : num;
                       }
            }
            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) {
                                 int num = s1.length() - s2.length();       
                                 return num == 0 ? s1.compareTo(s2) : num;
                     }
                }       
                TreeSet set = new TreeSet(new MyComparator());
                set.add(new Person());

##7.泛型
* 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.在接口上定义泛型
        * 和在类上定义一样

##8.迭代器
* 1.原理:集合的数据结构不同,所以存储方式不同,所以,取出方式也不同.这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可。
* 迭代器是一个内部类,在集合的内部定义了一个类,这个类实现了Iterator接口
* 2.使用
*
              List list = new ArrayList();
              list.add(1);
              list.add(3);
              Iterator<Integer> iterator = list.iterator<>();
              while(iterator.hasNext()){
                   System.out.println(iterator.next());
               }
* 3.常见问题
* ConcurrentModificationException:在迭代的时候给集合增加元素,删除元素造成的
* 解决方案:通过迭代器增加删除
* 4.Iterator 和 ListIterator的区别
        * 1.Iterator是ListIterator的父接口
        * 2.Iterator是Collection集合的公共的取出容器中元素的方式,对于List,Set都通用.而ListIterator是List集合的特有的取出元素的方式
        * 3.Iterator中只具备hasNext(),next(),remove()方法,可以删除被遍历到的元素
        * 4.ListIterator中具备对遍历到的元素进行增(add)删(remove)改(set)查(next)的方法,可以对元素逆向遍历previouse相对于next,hasPreviouse相对于hasNext(用的很少)

##9.集合的遍历
* 1.集合的遍历方式
        * 1.迭代
        * 2.将集合转换为数组
        * 3.获取集合的长度,通过get(索引)+for遍历(list集合)
        * 4.使用增强for循环
* 2.for循环遍历和迭代器遍历的区别
        * 1.最主要的区别就是remove方法,想要在循环的过程中删除元素就要用迭代器,因为迭代器的remove方法不仅会删除元素,还会维护一个标志,用来记录当前状态是不是可删除.而for循环角标是变化的,删除元素会报错,因为list.size()大小发生变化了
        * 2.ArrayList里面维护的是数组,顺序结构,所以用get方法获取比较快,因而用for循环
        LinkedList里面维护的是链表,链式结构,Iterator中的next()方法,采用的即是顺序访问的方法,因此用迭代器比较快



----------
##1.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()

##2.Map集合的两种遍历方式
* 1.遍历方式键找值(通过keySet()
*
                Set<String> keySet = map.keySet();
                for(String key : keySet){
                        System.out.println("key:"+key+"  value"+map.get(key));
                }
* 2.遍历方式键值对对象找键和值(通过entrySet()
*
                set<Entry<String, Integer>> entrySet = map.entrySet();
                for(Entry<STring, Integer> en : entrySet) {
                        System.Out.println(en.getKey() + "..." + en.getValue());
                }
##3.HashMap
* HashTable:线程安全,效率低,不允许null键和值,HashMap是JDK1.2版本出现的
* HashMap:线程不安全,效率高,允许null键和值,Hashtable是JDK1.0版本出现的
* LinkedHashMap:底层是链表实现的可以保证怎么存就怎么取

##4.TreeMap
* 统计字符串中每个字符出现的次数
*
                String str = "aaaabbbcccccccccc";
                char[] arr = str.toCharArray();                                               
                HashMap<Character, Integer> hm = new HashMap<>();       
               
                for(char c : arr) {                               
                        hm.put(c, hm.containsKey(c) ? hm.get(c) + 1 : 1);
                }
               
                for (Character key : hm.keySet()) {                                       
                        System.out.println(key + "=" + hm.get(key));
                }

##5.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)



作者: Hyperion    时间: 2016-5-27 22:33
mark记录一下




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2