Collections,Map以及Collections工具类复习

一 Collection

1.1概念

集合存储的优点: 初始化时长度可不定 提供的方法比较多 对于增删改 效率较高 可有序 可无序 可重复 可不重复

1.2 体系结构

请添加图片描述

/**
 * 分为Collection 和Map体系
 *Collection接口:  单列数据   常用的实现类   List 有序,可重复 Set 无序,不可重复
 *              ArrayList LinkedList Vector
 *              HashSet,Linked,TreeSet
 *      Map: 双列数据  key-value数据存储
 *          HashMap LinkedMap TreeMap  HashTable  Properties
 */
1.3 Collection中的方法
    @Test
    public void te1() {
        Collection coll = new ArrayList();
        Collection coll1 = new ArrayList();
        //boolean add(E e);//添加元素
        coll.add(new Date());
        System.out.println(coll.size());//1 有多少元素
        coll1.add(120);
        //addAll(Collection coll)
        coll.addAll(coll1);
        System.out.println(coll.size());//2
        System.out.println(coll);//相当于toString ArrayList的

        //boolean isEmpty(); 判断里面是否有数据
        System.out.println(coll.isEmpty());//false
        //void clear(); 清空元素 仍保留对象
        coll.clear();
        System.out.println(coll.isEmpty());//true
//         boolean contains(Object o);  判断的不是地址值而是内容
//         在判断是 会调用对象自己重写的equals 内容相等
        coll.add(110);
        System.out.println(coll.contains(110));//true
        Collection coll3 = Arrays.asList(110);
//        boolean containsAll(Collection<?> c); 判断coll3是否全部都在coll里面
        System.out.println(coll.containsAll(coll3));//true
//      boolean remove(Object o);  也是从第一个开始找 既然是找内容相等 就依然要调用equals
        System.out.println(coll.remove(110));
        coll.add(110);
//         boolean removeAll(Collection<?> c); 依然要调用equals
        System.out.println(coll.removeAll(coll3));//true
    }
    @Test
    public void te2() {
        Collection coll = new ArrayList();
        Collection coll1 = new ArrayList();
        //boolean add(E e);//添加元素
        coll.add(123);
        coll.add(456);
        coll1.add(123);
//        boolean retainAll(Collection<?> c);保留一样的,删除不一样的
        System.out.println(coll.retainAll(coll1));//true
        System.out.println(coll);
//        boolean equals(Object o);
        System.out.println(coll.equals(coll1));//true  ArrayList 是有序的 所以顺序不对也是false
//         int hashCode(); 返回当前对象的hash值
        System.out.println(coll.hashCode());
//        集合->Array数组Object[] toArray();
        Object[] b = coll.toArray();
//        数组->集合 public static <T> List<T> asList(T... a)
        List<int[]> ints = Arrays.asList(new int[]{123});
        System.out.println(ints);//[[I@4ee285c6] 一维数组 只有一个对象 认为是一个元素
        List arr = Arrays.asList(123, 456);
        System.out.println(arr);//[123, 456]
    }

2. Iterator 迭代器(遍历集合)

其对象主要用于遍历Collection集合中的元素, 主要就是为容器 遍历对象。

//         hasNext(); 判读是否还有下一个元素
//        next();指针下移并返回
//        void remove() 删除集合中的元素 删除 的是指针所指的元素
   @Test
    public void te3() {

        Collection coll = Arrays.asList(123, 456, false, "123");
        //Iterator<E> iterator();每次调用coll.iterator(); 都会返回一个新的Iterator对象
        Iterator iterator = coll.iterator();
        //iterator的遍历
        // boolean hasNext(); 判读是否还有下一个元素
        while (iterator.hasNext()) {
            //  E next(); 1.初始的时候指向的是第一个元素上面 2.指针下移 3.下移之后 把下移之后的元素返回
            System.out.println(iterator.next());
//            foreach 内部调用的仍然是迭代器
//              执行过程 就是 每次取出coll中的一个元素 赋值给Object obj

            for (Object obj : coll) {
                System.out.println(obj);
            }
        }

    }

3.ArrayList

3.1 概念

作为list的主要实现类 线程不安全的,效率高 底层使用 Object[]

3.2 jdk7和jdk8的源码区别
  //1.7源码 创建初始化为10的一个数组 然后不够以1.5倍容量进行扩充,并Arrays.copyOf()把之前的复制 相当于饿汉式
    //1.8 初始化时没有创建 而是add操作时进行创建 长度为10 的数组 其后相等 相当于懒汉式

4.LinkedList

4.1概念

对于频繁的 插入,删除操作 主要存着的就是对上一个元素和下一个元素的标识 可以把它转移给新的元素,只影响相邻的2个元素。
底层双向链表 既知道上面的,也知道下面的。

4.2底层实现
transient Node<E> first; transient Node<E> last; 默认值为null add(123)
    //把123封装到Node中   其内部的Node 体现了双向链表
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

5. Vector

5.1概念

作为list的古老实现类 线程安全的,效率低

5.2 底层使用
protected Object[] elementData;
//初始化为10 的数组扩容为原理数组的2倍 线程安全一般也不用

6.List的常用方法

@Test
    public void teList() {
        //List 主要就是比 Collection 多了几个索引的方法
        ArrayList aList = new ArrayList();
        aList.add(123);
        aList.add(456);
        aList.add(123);
        aList.add("hhh");
//           public void add(int index, E element)
        aList.add(2, 234);//在index 位置,插入element
        System.out.println(aList);//[123, 456, 234, 123, hhh]

        List l = Arrays.asList("aa", "bb");
// public boolean addAll(int index, Collection<? extends E> c) 在index位置上 添加一个集合
//        如果是 add(l) 是把l看成一个整体 即不管l有几个元素 添加进去时都会当成一个集合元素
        aList.addAll(1, l);
//        public E get(int index) 获取第index个元素
        System.out.println(aList.get(1));//aa
//      public int indexOf(Object o) 返回集合中首次出现的位置 不存在返回-1
        System.out.println(aList.indexOf(123));
//        public int lastIndexOf(Object o) 返回集合中最后一次出现的位置 不存在返回-1
//        public E remove(int index)  删除index位置的元素 返回删除的元素 删除之后后面往前移动
//        注意Collection 中也有个 boolean remove(Object o)  删除的是那个元素
        System.out.println("remove"+aList.remove(2));
//        public List<E> subList(int fromIndex, int toIndex)  返回的是左闭右开的集合
        System.out.println("subList"+aList.subList(1, 3));


    }

Set

1.并没有定义新的方法,主要是其父类Collection的
2.无序性:不等于随机性。并非按照数组的索引添加,而是按照数据的hash值决定的
3.不可重读性: 按照equals 判断是否相等,即要有重写equals 在判断前会进行hashCode

7.HashSet

7.1概念

作为set的主要实现类 可以存null值

7.2.底层分析
     *  添加元素的过程
     *  存放一个元素时计算其hash值,经过计算得出其应该放在那个位置上(这个是数组的索引)(底层实现是数组+链表),如果有第二个元素
     *  也在此位置上,判断其hash值是否相等,如果相等再判断equals方法,如果还相等,则不添加,反之hash或者equals不等,
     *  则加在其索引位置的链表上,以链表的方式存储,
     *  jdk7 该元素放在数组中指向原来的元素,
     *  jdk8原来的元素位置不变指向该元素
     *要求:向Set中添加数据 ,其 数据所在的类 要 重写equals和hashCode方法

8.LinkedHashSet

8.1概念

作为HashSet的子类 ,遍历时是按添加的顺序遍历的,在添加数据的同时还保存了两个引用,即上一个 和下一个,记录前一个数据 和后一个数据。

8.2底层结构理解

请添加图片描述

9.TreeSet

9.1 概念

可以按照添加对象的指定属性进行排序

9.2排序要求

1.要求添加的数据必须是相同类的对象
2。自燃排序 要求添加的的数据重写 public int compareTo(Object o) 排序从小到打大(默认)还是从大到小是根据compareTo(Object o) 决定的
特殊 TreeSet默认是按照compareTo比较的 如果这个方法返回0 默认认为就是相等的 则此不会进行添加
3.定制排序

 @Test
    public void teTreeSet(){
        //自然排序要求添加的的数据重写   public int compareTo(Object o) 
        //排序从小到打大(默认)还是从大到小是根据compareTo(Object o) 决定的
        Set set = new TreeSet();
        set.add(new User("aa",12));
        set.add(new User("cc",12));
        set.add(new User("bb",18));

// User{name='aa', age='12'}
//User{name='bb', age='18'}
//User{name='cc', age='12'}


        for (Object o:
                set) {
            System.out.println(o);//h h 123

        }
        //定制排序  public TreeSet(Comparator<? super E> comparator) 此时按照 Comparator中的compare 进行排序
       Comparator comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof User && o2 instanceof User)  {
                User user1 = (User)o1;
                User user2 = (User)o2;
                return  Integer.compare(user1.age, user2.age);

            }else {
                throw new RuntimeException("类型不匹配");
            }
            }
        };
        Set set1 = new TreeSet(comparator);
        set1.add(new User("aa",12));
        set1.add(new User("cc",14));
        set1.add(new User("bb",18));
        System.out.println("~~~~~~~~~~~~~~~~~~~");
        for (Object o:
                set1) {
            System.out.println(o);//h h 123

        }
// User{name='aa', age='12'}
//User{name='cc', age='14'}
//User{name='bb', age='18'}
    }

User中定义的compareTo

  @Override
    public int compareTo(Object o) {
        if (o instanceof User){
            User user = (User)o;
            //根据名字的顺序进行比较 此时调的是String的compareTo
            return this.name.compareTo(user.name);
        }else {
            throw new RuntimeException("类型不匹配");
        }

    }

二 Map

1.概念

双列数据 存储key-value数据

2.结构

    /*
   
HashMap  作为主要的实现类  线程不安全 效率高  可以存储null的key和Value

         		LinkedHashMap 遍历元素时,按照添加的顺序遍历的 在HashMap的基础上 增加了指针  频繁遍历是使用

                TreeMap  主要用来排序  ,此时考虑key 的自然排序或者定制排序,底层是红黑树  和TreeList
                Hashtable 古老实现类线程安全,效率低
                       Properties  key和value都是String  主要用来做配置文件
     */

请添加图片描述

3.Map结构理解

Map 中的key-value 结构 key无序,使用set的去存储不重复 所以key 所在的类要重写 equals 和 hashCode方法
value可重复 用collection存储 所在的类要重写 equals
Map中的Entry : key-value构成了Entry对象 无序,不可重复,用set储存

4.HashMap

1.概念

作为主要的实现类 线程不安全 效率高 可以存储null的key和Value

2.底层实现原理
/*底层:
        jdk7的时候 数组+链表 长度16的数组 Entry数组   put 时 计算hash值得到其存放位置  其位置为空时,添加成功 位置不为空时
        比较key的hash值 hash值不同添加成功 相同 比较equals 再相同 把新的value替换到原来的value上 反之 添加成功
        当put不下时 扩容为原来长度的两倍 扩容并非到16时才扩容 16*0.75时候(且要存放的位置非空)就扩容
        8的时候 链表+数组+ 红黑树 当链表长度大于8 且当前数组的长度大于64时会用红黑树
        临界值:length*0.75
        加载因子:0.75 小了数组利用率低 大了链表中的数据过多
        存在加载临界值的原因就是 既然是通过hash值计算的索引(具有不确定性),那就是不像数组那样 为空就去填充 ,或许一个位置通过链表存放了很多个,
        但是其还有很多位置为空
                new 的时候并没有赋予长度 当首次调用put时 创建长度为16的数组 底层数组是Node
    * */

请添加图片描述

5.LinkedHashMap

1.概念

遍历元素时,按照添加的顺序遍历的 在HashMap的基础上 增加了指针 频繁遍历时使用。

2.底层实现原理
    *       put 时调用的是Map的然后调用了 Map的putVal 然后调用了重写的的newNode
    *       然后 Entry继承了父类的Node 并添加了 before和after属性  记录元素的添加记录

6.TreeMap

1.概念

主要用来排序 ,此时考虑key 的自然排序或者定制排序,底层是红黑树 和TreeList

2.TreeMap 自然排序和定制排序

注:只能按照key进行排序

   @Test
    public void te3(){
        Map<String, Object> map = new TreeMap<>();
        map.put("aa",119);
        map.put("cc",110);
        map.put("bb",110);
        //1.自然排序  即实现Comparable接口
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Object o:
                entries) {
            System.out.println(o);
            //aa=119
            //bb=110
            //cc=110
        }
        //2.定制排序 实现Comparator接口
        Map<String, Object> map1 = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if ( o1 instanceof String && o2 instanceof String){
                    String str1 = (String)o1;
                    String str2 = (String)o2;
//                    加 - 号 是其相反的顺序 进行排序
                    return -str1.compareTo(str2);
                }else {
                    throw new RuntimeException("类型不匹配");
                }
            }
        });
        map1.put("aa",119);
        map1.put("cc",110);
        map1.put("bb",110);
        Set<Map.Entry<String, Object>> entries1 = map1.entrySet();
        for (Object o:
                entries1) {
            System.out.println(o);
                //cc=110
                //bb=110
                //aa=119
        }
    }

7. Map 的常用方法

请添加图片描述

  @Test
    public  void  te1(){
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> map1 = new HashMap<>();
//         V put(K key, V value); 添加一个键值对 如果key一样,返回值为上一个value 反之返回null
        System.out.println(map.put("aa", 110));//null
        System.out.println(map.put("aa", 120));//110
        map1.put("aa",119);
        map.put("bb",110);
        System.out.println(map);//{aa=120}
//        void putAll(Map<? extends K, ? extends V> m); 添加一个Map
        map.putAll(map1);//{aa=120, bb=110}
//        V remove(Object key); 返回remove里卖弄的value 不存在返回null
        System.out.println(map.remove("aa")); //119
//        void clear(); 清空数据 并不是删除此map对象
        map.clear();
//       V get(Object key); 返回其对应的value 不存在 返回null
        System.out.println(map1.get("aa"));//119
//         boolean containsKey(Object key); 是否包含指定的key boolean containsValue(Object value);是否包含指定的value
        System.out.println(map1.containsKey("aa"));//true
        System.out.println(map1.containsValue(119));//true
//         boolean isEmpty();
        System.out.println(map.isEmpty());//true
//        int size(); 返回有几个键值对
        System.out.println(map.size());//0

    }

8. 遍历

 @Test
    public void te2(){
        Map<String, Object> map = new HashMap<>();
        map.put("aa",119);
        map.put("bb",110);
        map.put("cc",110);
        //1.遍历所有的key    Set<K> keySet();
        Set<String> set = map.keySet();
        for (Object s:
             set) {
            System.out.println(s);
            //aa
            //bb
            //cc
        }
//        2.遍历所有的value  Collection<V> values(); 注意遍历key和value的白遍历顺序是一样的
        Collection<Object> values = map.values();
        for (Object o:
             values) {
            System.out.println(o);
                //119
                //110
                //110
        }
//        3.1遍历所有的key和value Set<Map.Entry<K, V>> entrySet();
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Object o:
             entries) {
            System.out.println(o);
            //aa=119
            //bb=110
            //cc=110
        }
//        3.2 遍历所有的key和value 用Iterator
        Set<Map.Entry<String, Object>> entries1 = map.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries1.iterator();
        while (iterator.hasNext()){
            Object o = iterator.next();
//            entrySet集合元素里面都是Entry
//            Entry 是Map 里面定义的内部接口  里面有getKey() 和getValue()  setValue(V value);
            Map.Entry entry = (Map.Entry) o;
            System.out.println(entry.getKey() + "-->" + entry.getValue());
                //aa-->119
                //bb-->110
                //cc-->110
        }

    }

9.Properties

9.1概念

Properties的key和value都是String 主要用来处理属性文件

9.2代码实现
public class PropertiesTest {
        //      Properties的key和value都是String  主要用来处理属性文件

    public static void main(String[] args) throws Exception {
        Properties properties = new Properties();
//        通过IO流获取配置文件 
        FileInputStream fis = new FileInputStream("jdbc.properties");
        properties.load(fis);
        System.out.println(properties.getProperty("name"));
        System.out.println(properties.getProperty("pwd"));
                //admin
                //123
//        流的关闭
        fis.close();
    }
}

jdbc.properties
注:不要有空格什么的,放在项目下,防止找不到文件

name=admin
pwd=123

三 Collections工具类

1.概念

Collections是用来操作Collection 和Map的一个工具类

2.一些常用的方法

    @Test
    public void te1(){
        List list = new ArrayList();
        list.add(8);
        list.add(12);
        list.add(23);
        list.add(4);
        System.out.println(list);//[8, 12, 23, 4]
//        public static void reverse(List<?> list) 反转
        Collections.reverse(list);
        System.out.println(list);//[4, 23, 12, 8]
//        public static void shuffle(List<?> list) 随机化
        Collections.shuffle(list);
        System.out.println(list);//无序 [12, 4, 8, 23]
//         public static <T extends Comparable<? super T>> void sort(List<T> list) 此时按照的是Integer里面的Comparator方法
        Collections.sort(list);
        System.out.println(list);//[4, 8, 12, 23]
//         public static void swap(List<?> list, int i, int j) 交换 list 里面的i和j元素
        Collections.swap(list,1,3);
        System.out.println(list);//[4, 23, 12, 8]
//         public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
//        public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
//        此时按照的是Integer里面的Comparator方法 的最大值和最小值
        System.out.println(Collections.max(list));//23
        System.out.println(Collections.min(list));//4
//         public static int frequency(Collection<?> c, Object o) list集合里面 o出现了几次
        System.out.println(Collections.frequency(list,12));//1


//         public static <T> void copy(List<? super T> dest, List<? extends T> src)
//        注意源码中 if (srcSize > dest.size())
//                  throw new IndexOutOfBoundsException("Source does not fit in dest");
//        所以应该这样copy
        List destList = Arrays.asList(new Object[list.size()]);
        Collections.copy(destList,list);
        System.out.println(destList);//[4, 23, 12, 8]


    }

3.当涉及到线程安全时

提供了多个synchronized…的方法 使集合包装成线程同步的集合,从而解决多线程安全问题。
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值