集合的使用和原理解读

目录

一、Collection集合

 1、collection集合的通用方法

<1>  add()        添加元素

<2>  clear()       清空所有元素

<3>  contains()    查看是否包含某个元素

<4>  size()           查看集合的大小

<5>  isEmpty       判断集合是否为空

<6>  toArray()        把集合元素存储到数组中

<7>  addAll()         把集合的元素拷贝到另一个相同类型的集合​编辑

 2、collection集合的遍历

 <1>iterator使用迭代器遍历

<2>foreach/增强for循环

二、List集合(collection子接口)

 1、List集合的特点

2、List集合的独有方法

 <1>        add(int index ,E element)  在集合指定索引位置,插入元素

 <2>        remove( int index )删除指定索引位置的元素

 <3>        set(int index , E element) 修改指索引位置的元素

 <4>        get(int index)    获取指定索引位置的元素

3、ArrayList的底层原理

 4、LinkedList及其独有方法

<1>addFirst()        列表开头插入元素

<2>addLast()        列表末尾插入元素

<3>getFirst()        获取表头数据

<4>getLast()        获取表尾数据

<5>removeFirst()        移除表头数据

<6>removeLast()        移除表尾据数

5、循环遍历时如何删除元素

<1>迭代器:使用迭代器自身的remove()方法

<2>普通for循环1:正序删除

<3>普通for循环1:倒序删除

三、set集合

四、Map集合

 1、map集合常用API

<1>put(K key , V value)

<2>remove(Object key) 删除键值对元素

<3>clear()清空集合

<4>containsKey(object key)

<5>containsValue(object value)

<6>isEmpty()

<7>size()

<8>keySet()  把所有的键放入set集合

<9>values() 把所有的值存入collection集合

<10>putAll() Map集合的拷贝

2、Map的遍历

1、通过遍历键取值

2、获取key-value(代码里有详细解释)

3、Lambda表达式




一、Collection集合

 首先通过这张图来了解下collection的集合的家族。

 1、collection集合的通用方法

<1>  add()        添加元素

<2>  clear()       清空所有元素

<3>  contains()    查看是否包含某个元素

<4>  size()           查看集合的大小

<5>  isEmpty       判断集合是否为空

<6>  toArray()        把集合元素存储到数组中

<7>  addAll()         把集合的元素拷贝到另一个相同类型的集合

 示例代码:

package com.wrx;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class collection {

    public static void main(String[] args) {
//        collection集合的常用API
        Collection<String> list = new ArrayList<>();
//        1.加入元素           :add()
                list.add("wrx");
                list.add("111");
                list.add("222");
                list.add("333");
                list.add("444");
                list.add("333");
                System.out.println(list);//输出list的内容(不算遍历)
//        2.清空集合元素       :clear()
//              list.clear();
                System.out.println(list);
//        3.判断集合是否为空   :isEmpty()
                boolean a = list.isEmpty();
                System.out.println(a);//结果应该是false,集合非空
//        4.判断集合是否包含某个元素
                boolean b = list.contains("wrx");
                System.out.println(b);//结果应该为true,集合里包含这个元素

//        5.删除某个元素(根据元素内容):remove
//          这种删除方式,只会删除集合里第一个相同的元素,后面的相同元素保留
                boolean c = list.remove("wrx");
                System.out.println(c);//结果应该为true,确实删除了这个元素
//        6.获取集合的大小         : size()
                System.out.println(list.size());
//        7.集合转换为数组  :toArray()
                Object[] array = list.toArray();//把集合转化为object类型的数据,存入数组中
                System.out.println(list);
                System.out.println(Arrays.toString(array));//输出数组
//        8.集合的数据拷贝   :addAll()
                 Collection<String> c1 = new ArrayList<>();
                 Collection<String> c2 = new ArrayList<>();
                 c1.add("1");
                 c1.add("2");//此时c1为[1,2]
                 c2.add("3");
                 c2.add("4");//此时c2为[3,4]
                 c1.addAll(c2);//将c2复制进入c1,此时c1为[1,2,3,4]
                 System.out.println("c1:"+c1); //输出结果 c1:[1,2,3,4]


    }

}

 2、collection集合的遍历

 <1>iterator使用迭代器遍历

 当我们创建迭代器对象时候,迭代器对象默认指向索引为0的位置,也就是第一个数据。

(1)        next()                 取出当前位置的元素,并且将迭代器对象指向下一个位置。

(2)        hasNext()          判断当前索引位置是否有元素。

   HashSet<String> set = new HashSet<>();
                    set.add("wrx");
                    set.add("yll");
                    set.add("zyf");
                    set.add("wxy");
                    Iterator<String> it3 = set.iterator();
                    while(it3.hasNext()){
                        System.out.println(it3.next());
                    }

<2>foreach/增强for循环

(1)增强for既可以遍历数组也可以遍历集合

(2)内部原理是迭代器iterator,相当于迭代器的简化写法

(3)实现Iterator接口的类才可以使用迭代器和增强for,collection已经实现Iterator接口

 示例代码:

//            5.使用增强for循环来遍历集合
                    Collection<String> c  = new ArrayList<>();
//                                          数据填充
                                            c.add("wrx");
                                            c.add("yll");
                                            c.add("zyf");
                                            c.add("wxy");
//                  使用增强for:快捷方式  c.for
                    for (String s : c) {
                        System.out.println(s);
                    }

注意:

 当我们想修改集合元素时候,只修改拷贝过来的局部变量是不行的。

 如果需要修改的话需要使用普通的for循环或者while循环。

//         修改元素内容
        ArrayList<String> c2  = new ArrayList<>();
//                                          数据填充
                     c2.add("wrx");
                     c2.add("wxy");
                     c2.add("yll");
                     c2.add("zyf");
                     c2.add("wxy");
//         使用普通for循环遍历修改
        for (int i = 0; i < c2.size(); i++) {
            if (c2.get(i)=="wrx"){
                c2.set(i,"wrx6666");
            }
            System.out.println(c2.get(i));
        }

二、List集合(collection子接口)

 1、List集合的特点

2、List集合的独有方法

由于List集合支持索引,所以多了很多List集合独有的方法。

 <1>        add(int index ,E element)  在集合指定索引位置,插入元素

 <2>        remove( int index )删除指定索引位置的元素

 <3>        set(int index , E element) 修改指索引位置的元素

 <4>        get(int index)    获取指定索引位置的元素

代码示例:

package com.wrx;

import java.util.ArrayList;
import java.util.List;

public class collection_03_List_methods {


    public static void main(String[] args) {
//        创建ArrayList集合并且填充数据
                List<String> list = new ArrayList<>();
//              1.在指定索引位置添加数据   add( int index , E element)
                    list.add(0,"wxy");
                    list.add(1,"wrx");
                    list.add(2,"zyf");
                    list.add(3,"yll");
                    list.add(4,"qw");
                    System.out.println(list);
                    for (String s : list) {
                        System.out.println(s);//集合遍历
                    }
//              2.删除指定是索引位置元素   remove(int index)
                    list.remove(4);//  删除了qw
//              3.根据索引获取元素    get(int index)
                    System.out.println(list.get(1));//获取的应为wrx
//              4.根据索引修改某个位置的元素
                    list.set(1,"wrx666666");
                    System.out.println(list.get(1));//输出信息为wrx666666
    }
}

3、ArrayList的底层原理

   基本原理:   ArrayList底层是基于数组实现的,刚开始会创建一个长度为10的数组,有一个变量size,一开始指向0的位置,并且存的元素个数(刚开始是0),每插入一个元素,size后移一位,size里的存的元素个数加一。

   如何插入: 如果我们想在索引为2的位置插入数据(如下图),那么需要先把size位置与插入的位置有多远,就先后移动几位,然后遍历2,3位置的元素,往后移动到size之前一位,这时候就可以在2的位置插入元素。

   扩容:数组长度为10,总会用完的,当size指向的索引值等于数组的最大长度史,那么就会新建一个长度为15的数组(1.5倍扩容),并且把原本的数组元素迁移过来。

 4、LinkedList及其独有方法

<1>addFirst()        列表开头插入元素

<2>addLast()        列表末尾插入元素

<3>getFirst()        获取表头数据

<4>getLast()        获取表尾数据

<5>removeFirst()        移除表头数据

<6>removeLast()        移除表尾据数

 代码示例:

package com.wrx;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;

public class collection_04_List_LinkedList {
    public static void main(String[] args) {
//        创建LinkedList并且填充数据
                LinkedList<String> lk = new LinkedList<>();
//      1.进栈(先进后出):   压入数据 addFirst()
                lk.addFirst("wxy");
                lk.addFirst("zyf");
                lk.addFirst("yll");
                lk.addFirst("qw");
                lk.addFirst("wrx");//[wrx, qw, yll, zyf, wxy]
                System.out.println(lk);//输出的内容[wrx, qw, yll, zyf, wxy]
//       2.获取列表第一个元素  getFirst()
                System.out.println(lk.getFirst());//结果为wrx
//       3.获取列表最后一个元素
                System.out.println(lk.getLast());//结果为wxy
//       4.出栈      弹出数据 : removeFirst()
                lk.removeFirst();//弹出的数据为wrx(后进先出原则)
                System.out.println(lk);//输出的集合内容[qw, yll, zyf, wxy]
                System.out.println("----------------------------------------");
//        清空数据
                lk.clear();
//       1.队列  入队 addLast()
                lk.addLast("wxy");
                lk.addLast("wrx");
                lk.addLast("zyf");
                lk.addLast("yll");
                System.out.println(lk);//结果为[wxy, wrx, zyf, yll]
//       2.出队列  出队  removeFirst()
                lk.removeFirst();//移除的是wxy
                System.out.println(lk);//结果为[wrx, zyf, yll]


    }
}

5、循环遍历时如何删除元素

 注意:增强for循环和lambda表达式都无法完成这一操作。

<1>迭代器:使用迭代器自身的remove()方法

 详情请看代码:里面有解释原因

package com.wrx;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class collection_05_遍历删除问题 {
    public static void main(String[] args) {
        //        创建ArrayList集合并且填充数据
        List<String> lists = new ArrayList<>();
//              1.在指定索引位置添加数据   add( int index , E element)
                    lists.add(0,"wxy");
                    lists.add(1,"wrx");
                    lists.add(2,"wrx");
                    lists.add(3,"zyf");
                    lists.add(4,"yll");
                    lists.add(5,"qw");
                    System.out.println(lists);
//          遍历删除wrx
//        方式一:使用迭代器
                Iterator<String> it = lists.iterator();
                while(it.hasNext()){
                    String ele = it.next();
                    if (ele.equals("wrx")){
                        it.remove();//注意删除的时候,要用迭代器的删除方法(原因如下)
                    }
                }
//                原因:
        /**原因:
         * 最一开始迭代器指向第一个元素如下
         *
         *  [wxy, wrx, wrx, zyf, yll, qw]
         *   ^
         *
         * 但是当调用完next()方法时,获取到当前指向的数据后,迭代器指针就后移一位如下:
         *  it.next()   执行next()
         *
         * [wxy, wrx, wrx, zyf, yll, qw]
         *        ^
         *
         * 如果我们想删除wxy,如果我们使用集合的remove()方法,就会出错,因为地址已经后移动了
         * 并且如果,我们像删除所有wrx,我们会发现两个wrx相邻的会漏删一个,wrx不相邻就报错了
         *
         * 迭代器的remove()方法可以规避这个问题
         *
         */


    }
}

<2>普通for循环1:正序删除

package com.wrx;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class collection_05_遍历删除问题 {
    public static void main(String[] args) {


//        方式二:for循环  (1)正向删除
//                  创建ArrayList集合并且填充数据
                    List<String> list = new ArrayList<>();
//              1.在指定索引位置添加数据   add( int index , E element)
                    list.add(0,"wxy");
                    list.add(1,"wrx");
                    list.add(2,"wrx");
                    list.add(3,"zyf");
                    list.add(4,"yll");
                    list.add(5,"qw");
                    System.out.println(list);
//          正向删除:删完索引减一
                    for (int i = 0; i < list.size(); i++) {
                        if (list.get(i).equals("wrx")){
                            list.remove(i);
                            i--;//一定要索引减一,因为删完之后集合后面的数据会向前迁移一位.详情看下面
                        }
                    }
                    System.out.println(list);
        /**索引减一原因:
         * 当我们的for循环走到i=1时,出现第一个wrx时候
         *
         *       [wxy, wrx, wrx, zyf, yll, qw]
         * i的值:       ^                      1
         *
         * 此时的i=1,我们用equals比较后根据索引删除了,第一个wrx确实删除了,但是集合的结构会变化,并且循环继续走到i=2
         *       [wxy,  wrx, zyf, yll, qw]
         * i的值:            ^                 2
         *
         * 此时为我们发现,第二个wrx前移了,我们的i增加了1,索引不匹配了因此我们在根据索引取值,就会漏一个wrx
         *
         */


    }
}

<3>普通for循环1:倒序删除

package com.wrx;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class collection_05_遍历删除问题 {
    public static void main(String[] args) {

//        方式三:for循环  (2)倒序删除
//                  创建ArrayList集合并且填充数据
                    List<String> list1 = new ArrayList<>();
//              1.在指定索引位置添加数据   add( int index , E element)
                    list1.add(0,"wxy");
                    list1.add(1,"wrx");
                    list1.add(2,"wrx");
                    list1.add(3,"zyf");
                    list1.add(4,"yll");
                    list1.add(5,"qw");
                    System.out.println(list1);
//              倒序删除
                    for (int i = list1.size()-1; i >=0; i--) {//此时需要把for循环的顺序反过来,具体看以下解释
                        if (list1.get(i).equals("wrx")){
                            list1.remove(i);
                        }
                    }
                    System.out.println(list1);
            /**倒序原因:
             * 由于是倒叙我们的for循环的i一开始是集合的长度减一
             *       [wxy, wrx, wrx, zyf, yll, qw]
             * i的值:                          ^    i=5
             * 当循环继续到第一个wrx时候i=2
             *       [wxy, wrx, wrx, zyf, yll, qw]
             * i的值:            ^                   i=2
             *
             * 我们用i当作索引删除wrx,集合发生变化,被删除的地方的后面的数据会向前移动
             * 同时for循环也在进行i也会减1,结果就是现在的情况,刚好i还是指向下一个元素,不会漏掉
             *       [wxy,  wrx, zyf, yll, qw]
             * i的值:        ^                       i=1
             * 此时我们又可以根据i当作索引删除也不会漏掉元素
             *
             */
    }
}

三、set集合

 set集合详细见我的Java常见面试题开头部分。

链接如下:

http://t.csdn.cn/beyt9

四、Map集合

 1、map集合常用API

<1>put(K key , V value)

<2>remove(Object key) 删除键值对元素

<3>clear()清空集合

<4>containsKey(object key)

<5>containsValue(object value)

<6>isEmpty()

<7>size()

<8>keySet()  把所有的键放入set集合

<9>values() 把所有的值存入collection集合

<10>putAll() Map集合的拷贝

 代码示例:

package com.wrx.Map;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Map_01_API {

    public static void main(String[] args) {

//  1.创建Map集合
        Map<Integer,String> map = new HashMap<>();
//        2.填充数据 put(K key ,V value)
        map.put(1,"wxy");
        map.put(2,"wrx");
        map.put(3,"yll");
        map.put(4,"zyf");
        System.out.println(map);
//        3.清空集合 clear()
//        map.clear();
//        System.out.println(map);
//        4.判断集合是否为空 isEmpty()
        System.out.println(map.isEmpty());//输出应为false
//        5.根据键取值 get(K key)
        System.out.println(map.get(1));//输出结果应为wxy
//        6.根据键删除整个元素 remove(K key)
        System.out.println(map.remove(1));//返回的值为被删除的键的值
//        7.判断是否包含某个键 containsKey(K key)
        System.out.println(map.containsKey(1));//1已经被删除了,此时返回的应该的是false
//        8.判断是否包含某个值,containsValue( V value )
        System.out.println(map.containsValue("wrx"));//wrx没有被删除,所以返回值是true
//        9.获取全部的键 keySet()
        Set<Integer> sets = map.keySet();
        System.out.println(sets);//返回值为[2,3,4]
//        10.获取全部的值 values()
        Collection<String> values = map.values();
        for (String value : values) {
            System.out.println(value);
        }
//        11.集合的拷贝  putAll(Map<T,T> map)
        Map<Integer, String> map1 = new HashMap<>();
        map1.putAll(map);
        System.out.println("map1:"+map1);//map1:{2=wrx, 3=yll, 4=zyf}
        System.out.println("map:"+map);//map:{2=wrx, 3=yll, 4=zyf}


    }
}

2、Map的遍历

1、通过遍历键取值

package com.wrx.Map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class Map_02_iterator {

    public static void main(String[] args) {

//        1.创建Map集合
        Map<Integer,String> map = new HashMap<>();
//        2.填充数据 put(K key ,V value)
        map.put(1,"wxy");
        map.put(2,"wrx");
        map.put(3,"yll");
        map.put(4,"zyf");
        System.out.println(map);
//        遍历方式(一):用键找值
//        1.先把所有的key放进set集合里,遍历set集合,通过key来获取value
        Set<Integer> set1 = map.keySet();
//        2.遍历Set集合通过key获取value
        for (Integer integer : set1) {
            System.out.println(integer+"="+map.get(integer));//通过Key来获取value
        }


    }
}

2、获取key-value(代码里有详细解释)

package com.wrx.Map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class Map_02_iterator {

    public static void main(String[] args) {

//        1.创建Map集合
        Map<Integer,String> map = new HashMap<>();
//        2.填充数据 put(K key ,V value)
        map.put(1,"wxy");
        map.put(2,"wrx");
        map.put(3,"yll");
        map.put(4,"zyf");
        System.out.println(map);
//        遍历方式(二):直接找key-value
//        1.把map集合的数据类型封装成key-value(一个整体)类型的数据
//        使用entrySet()方法,就是把key和value组成一个整体存入entrySet的对象
//        Map.Entry<Integer, String>对象都存了一个key-value
//        然后把entrySet对象存入set集合。
        Set<Map.Entry<Integer, String>> entries = map.entrySet();
//        2.遍历set集合,通过Map.Entry<Integer, String>的对象获取key和Value
        for (Map.Entry<Integer, String> entry : entries) {
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"====>"+value);
        }
        /**方式二的解释:
         * map集合原本如下
         * {1=wxy, 2=wrx, 3=yll, 4=zyf}
         * 1:  使用entrySet()方法
         * 2:  此时创建entry<T ,T >接口的实现类对象,并且把key-value键值对类型的数据进行封装
         *      (1=wxy),( 2=wrx), (3=yll),( 4=zyf)
         *
         * 3:  上图是每个entry对象里面存的数据,然后放进set集合
         * set<Map.Entry<Integer, String>>  entries
         * [(1=wxy),( 2=wrx), (3=yll),( 4=zyf)]
         *  此时里面存的是每个Map.Entry<Integer, String>类型的对象
         * 4:遍历set集合获取这个封装的entry对象
         * 5:根据entry对象使用getKey()和getValue()来获取一对键值
         */




    }
}

3、Lambda表达式

JDK1.8以后开始使用

package com.wrx.Map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class Map_02_iterator {

    public static void main(String[] args) {
//        1.创建Map集合
        Map<Integer,String> map = new HashMap<>();
//        2.填充数据 put(K key ,V value)
        map.put(1,"wxy");
        map.put(2,"wrx");
        map.put(3,"yll");
        map.put(4,"zyf");
        System.out.println(map);
//        遍历方式(三):Lambda表达式
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer i, String s) {
                System.out.println(i+"==========>"+s);
            }
        });
//        简化模式
        map.forEach( (k,v) -> System.out.println(k+"==========>"+v));






    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值