JAVA 集合类(一)

目录

java集合框架

集合框架设计目标

Java集合具备的特点

集合框架类型

Java集合框架图

java集合使用Demo

Java集合框架的工具类

Arryas的asList方法测试Demo

Arrays部分功能测试Demo

Collections测试Demo

Comparable 与 Comparator

测试Demo

集合遍历方式

常见的遍历方式

集合遍历demo


java集合框架

集合框架设计目标

  • 该框架必须是高性能的,基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性
  • 对一个集合的扩展和适应必须是简单的

Java集合具备的特点

  • 只能存储引用类型,不能存储基本数据类型(可以存储基本数据类型包装类)
  • 存储对象的引用,对象本身在堆内存
  • 可以存储不同的数据类型(泛型),不建议使用
  • 长度可变

备注:数组可以存储基本数据类型和引用数据类型;长度不可变;只能存储一种数据类型

集合框架类型

常用类型

实现类

数据结构

有序

允许空

线程安全

场景

List

ArrayList

数组

Y

Y

不同步

元素有序;可重复;查询快,增删慢

Vector

数组

Y

Y

同步

同ArrayList且线程安全(不建议使用合)

LinkedList

双向链表

Y

Y

不同步

元素有序;可重复;查询慢,增删快

Map

HashMap

哈希表

N

Y

不同步

(k,v)形式数据结构

HashTable

哈希表

N

N

同步

(k,v)形式数据结构;线程安全(不建议使用)

TreeMap

红黑树

N

N

不同步

(k,v)形式数据结构 ; k排序(自然排序,定时排序)

LinkedHashMap

链表+哈希表

Y

Y

不同步

HashMap子类; (k,v)形式数据结构;元素有序(插入顺序,访问顺序)

Set

HashSet

Map

N

Y

不同步

不可重复;元素无序

TreeSet

N

N

不同步

不可重复;元素排序(自然排序,定时排序)

LinkedHashSet

Y

Y

不同步

HashSet子类;不可重复;元素有序(插入顺序)

备注:

  • 哈希表=数组+链表/红黑树
  • 是否有序是指:插入顺序
  • 线程安全的集合可使用Collections提供的创建同步控制方法包装的线程安全集合
  • Collections提供了集合排序方法

Java集合框架图

  图片来源:https://www.runoob.com/java/java-collections.html

   

java集合使用Demo

ArrayList测试Demo

/**
 * list集合的测试
 *     ArrayList:有序集合;底层结构数组;非线程安全
 *     Vector: 有序集合;底层结构数组;线程安全
 *     LinkList :有序集合;底层循环双向链表;非线程安全
 */
@Test
public void testArrayList(){
    ArrayList<String> arr1 = new ArrayList<>();

    // 添加元素
    arr1.add("a1");     //添加元素到末尾
    arr1.add("a2"); arr1.add("a3");
    arr1.add(null);     //元素支持NULL
    arr1.add("a3"); arr1.add("a6");
    arr1.add("a5"); arr1.add("a4");
    arr1.add(1,"a0");   //指定位置添加元素
    log.info("新增集合结果:{}",arr1);

    // 修改元素
    arr1.set(0,"a1_1");
    log.info("修改后集合:{}",arr1);

    // 查询元素
    log.info("查询指定下标的元素:{}", arr1.get(0));               //查询指定下标的元素
    log.info("查询元素第一次出现的位置:{}", arr1.indexOf("a0"));   //查询元素第一次出现的位置
    log.info("判断集合是否包含指定元素:{}", arr1.contains("a3"));  //判断集合是否包含指定元素
    log.info("forEach查询元素结果见下一行:");
    arr1.forEach(str -> System.out.print(str + " -> "));
    System.out.println();

    // 删除元素
    String remove = arr1.remove(0);             //根据下标删除
    log.info("删除第0个元素:{},目前元素集合:{}", remove, arr1);
    boolean removeFlag = arr1.remove(null);     //删除指定的第一个元素
    log.info("删除指定元素null结果:{},目前集合元素:{}", removeFlag, arr1);
    arr1.removeIf(str -> "a3".equals(str));
    log.info("removeIf删除a3元素后集合:{}", arr1);
    //removeAll、removeRange ......
    arr1.clear(); //删除所有元素
    log.info("删除所有元素,目前集合:{},集合大小:{}", arr1, arr1.size());
}

      

LinkedList测试Demo

/**

     * LinkedList demo

     *   主要方法demo

     *   入队列:push、offer  出队列:poll、pop

     *   入队列:add  出队列:remove

     */

    @Test

    public void testLinkedList(){

        LinkedList<String> list = new LinkedList<>();

        list.add("a1");list.add("a2");list.add("a3");

        list.offer("a4");

        log.info("新增LinkedList集合:{}", list);

 

        //poll、pop、remove

        log.info("poll第一个元素:{},集合:{}", list.poll(), list);

        log.info("pop第一个元素:{},集合:{}", list.pop(), list);

        log.info("pop第一个元素:{},集合:{}", list.removeFirst(), list);

 

        //push、offer、add

        list.push("a3");

        log.info("push第一个元素:a3,集合:{}", list); //队列头添加元素

        log.info("push第一个元素:{},集合:{}", list.offerFirst("a2"), list); //队列头添加元素

        list.addFirst("a1");

        log.info("push第一个元素:a1,集合:{}", list); //队列头添加元素

    }

      

HashSet测试Demo

/**

     * set 测试demo

     *    HashSet 无序集合 ; 底层同HashMap  ;非线程安全

     *    TreeSet 无序集合 ; 底层同TreeMap ;非线程安全

     *    LinkedHashSet 有序集合;底层同LinkedHashMap;非线程安全

     */

    @Test

    public void testHashSet(){

        HashSet<String> set = new HashSet<>();

        set.add("a1");set.add("a1");

        set.add("a2");set.add("a3");

        log.info("新增set集合:{}", set);

        log.info("删除set集合元素:{},集合:{}", set.remove("a3"), set);

    }

      

TreeSet测试Demo

@Test

    public void testTreeSet(){

        TreeSet<String> treeSet = new TreeSet<>();

        treeSet.add("a1");treeSet.add("a3");

        treeSet.add("a5");treeSet.add("a6");

        treeSet.add("1");treeSet.add("2");treeSet.add("3");

        log.info("新增的treeSet集合:{}",treeSet);

 

        //查询

        log.info("返回集合中>=给定值单个元素:{}",treeSet.ceiling("a2"));

        log.info("返回集合中<=给定值单个元素:{}",treeSet.floor("a2"));

        log.info("返回集合中>给定值单个元素:{}",treeSet.higher("a2"));

        log.info("返回集合中<给定值单个元素:{}",treeSet.lower("a2"));

        log.info("返回集合中<给定值的集合:{}",treeSet.headSet("a2",false));

        log.info("返回集合中>给定值的集合:{}",treeSet.tailSet("a2",false));

        log.info("返回区间集合:{}",treeSet.subSet("3","a5")); //[3~a5)

 

        //删除

        log.info("set集合poll元素:{},集合:{}",treeSet.remove("1"),treeSet);

        log.info("set集合poll元素:{},集合:{}",treeSet.pollFirst(),treeSet);

    }

      

HashMap测试Demo

/**

     * map 测试demo

     *    HashMap 无序集合 ; 哈希表 ;非线程安全

     *    HashTable 无序集合 ; 哈希表 ;线程安全

     *    TreeMap  无序集合; 红黑树 ;非线程安全

     *    LinkedHashMap 有序集合; 比HashMap多一个链表维护顺序 ;非线程安全

     */

    @Test

    public void testHashMap(){

        HashMap<String,String> map = new HashMap<>();

 

        //新增

        map.put("01","a01");

        map.put("02","a02");

        map.put("03","a03");

        log.info("新增map集合:{}",map);

 

        //修改

        log.info("map集合替换01:{},集合:{}",map.replace("01","a01_2"),map);

         log.info("map的compute方法:{},集合:{}",map.computeIfPresent("02",(k,v)-> v+"_comp..."), map);

 

        //查询

        log.info("map集合返回键对应的值:{}",map.get("01"));

        log.info("map集合返键值对集合:{}",map.entrySet());

        log.info("map集合返键集合:{}",map.keySet());

        log.info("map集合返值集合:{}",map.values());

        log.info("map集合的包含对应的key:{}",map.containsKey("01"));

        log.info("map集合的包含对应的value:{}",map.containsValue("a01"));

 

        //删除

        log.info("map集合根据key删除指定的value:{},集合:{}",map.remove("01"),map);

    }

      

TreeMap测试Demo

@Test

    public void testTreeMap(){

        TreeMap<String,String> map = new TreeMap<>();

 

        //新增

        for(int i=0;i<8;i++){

            map.put(String.valueOf(i),"a"+i);

        }

        log.info("新增map集合:{}",map);

 

        //区间查询单个键值对

        log.info("集合中>=固定key值的键值对-单个:{}",map.ceilingEntry("5"));

        log.info("集合中<=固定key值的键值对-单个:{}",map.floorEntry("5"));

        log.info("集合中>固定key值的键值对-单个:{}",map.higherEntry("5"));

        log.info("集合中<固定key值的键-单个:{}",map.lowerEntry("5"));

 

        //区间查询键值对集合

        log.info("集合中<固定key值的键值对-集合:{}",map.headMap("5"));

        log.info("集合中>=固定key值的键值对-集合:{}",map.tailMap("5"));

        log.info("集合中区间key值的键值对-集合:{}",map.subMap("1","5")); //[1~5)

    }

      

Java集合框架的工具类

  • Arrays: 该类包含用于操作数组的各种方法(如排序和搜索),该类还包含一个静态工厂,可以将数组视为列表
  • Collections:集合对象的工具类,提供了操作集合的工具方法

    Arrays主要方法:  ①转列表asList() ②查询 binarySearch() ③复制 copyOf()

                                   ④比较 equals()  ⑤填充 fill()  ⑥排序 sort()

   Arryas的asList方法测试Demo

             . 返回的list是private static class Arrays.ArrayList<E>,非ArrayList未完全实现List接口

             . 定长集合;无add(),remove()方法(抛异常:java.lang.UnsupportedOperationException)

             . Arrays.asList将外部数据引用"=="方式赋予内部的泛型数组,本质执行同一个数组

             . 不支持基本数据类型转换

/**

     * Arrays测试demo

     *   ①转列表asList()

     *        . 返回的list是private static class Arrays.ArrayList<E>,非ArrayList

     *        . 定长集合;无add(),remove()方法(抛异常:java.lang.UnsupportedOperationException)

     *        . Arrays.asList将外部数据引用"=="方式赋予内部的泛型数组,本质执行同一个数组

     *        . 不支持基本数据类型转换

     */

    @Test

    public void testArraysAsList(){

        //定义数组

        String[] arr = {"1","2","3","6","5","4"};

        log.info("定义数组arr:{}",arr);

 

        //返回list是固定长度;未实现部分List方法不具备add,remove方法

        List<String> stringList= Arrays.asList(arr);

        stringList.set(0,"99");

        log.info("asList转换数组修改元素后集合:{}",stringList);

 

        //Arrays.asList将外部数据引用"=="方式赋予内部的泛型数组,本质执行同一个数组

        log.info("asList转换后,原数组的值变化了:{} \r\n",Arrays.toString(arr));

 

        //ArrayList包装Arrays.asList()方法创建的集合

        ArrayList<String> list = new ArrayList<>(stringList);

        list.set(0,"100");

        log.info("ArrayList集合转换后的集合:{}",list);

        log.info("ArrayList集合转换后的stringList集合:{}", stringList);

        log.info("ArrayList集合转换后的原数组:{} \r\n",Arrays.toString(arr));

 

        //不支持基本数据类型转换

        int [] arr2 = {1,2,3,6,5,4};

        List<int[]> ints = Arrays.asList(arr2); //列转换

        log.info("基本数据类型转换为长度为1,元素为其本书的集合:{},长度:{}",ints,ints.size());

 

        //不支持基本数据类型解决方案:①使用spring的CollectionUtils工具类 ②java8的流

        List<Integer> intList = CollectionUtils.arrayToList(arr2);

        log.info("基本数据类-spring工具类转换为集合:{}",intList);

        Arrays.stream(arr2).boxed().collect(Collectors.toList());

        log.info("基本数据类-java8方式转换为集合:{}",intList);

    }

      

Arrays部分功能测试Demo

/**

     * Arrays测试demo

     *   ②排序 sort() ③查找 binarySearch() ④复制 copyOf()

     *   ⑤比较 equals() ⑥填充 fill()

     */

    @Test

    public void testArraysOthers(){

        //定义数组

        String[] arr = {"1","2","3","6","5","4"};

        log.info("定义数组arr:{}",Arrays.toString(arr));

 

        //排序 sort()

        Arrays.sort(arr);

        log.info("排序后数组顺序{}",Arrays.toString(arr));

 

        //查找 binarySearch();需要先排序

        log.info("arrays.binarySearch查询5的位置:{}",Arrays.binarySearch(arr,"5"));

 

        //复制 copyOf()

        String[] stringCopy = Arrays.copyOf(arr, 8);

        log.info("复制数组:{}",Arrays.toString(stringCopy));

 

        //比较 equals() 相同的顺序中包含相同的元素

        log.info("比较数组结果:{}",Arrays.equals(arr, new String[]{"1","2","3","6","5","4"}));

        log.info("比较数组结果:{}",Arrays.equals(arr, new String[]{"1","2","3","4","5","6"}));

 

        //填充 fill()

        Arrays.fill(arr,"99");

        log.info("数组填充后:{}",Arrays.toString(arr));

    }

      

     Collection主要方法: ①添加元素addAll() ②排序 sort() ③查找 binarySearch() ④复制copy()

                                     ⑤替换 replaceAll() ⑥填充 fill()  ⑦反转 reverse()

                                     ⑧不可变集合 unmodifiable*      ⑨同步集合 synchronized*

Collections测试Demo

/**

     * Collection测试demo

     * . 添加元素到指定集合  .排序 .查找元素

     * .复制 .替换 .填充 .反转  .指定不可修改集合 .集合同步

     */

    @Test

    public void testCollections() {

        List<String> list = new ArrayList<>();

        list.add("1");list.add("2");list.add("3");

        log.info("初始化集合:{}",list);

 

        //添加元素到指定集合 addAll()

        Collections.addAll(list,new String[]{"6","5","4"});

        log.info("添加元素后的集合:{}",list);

 

        //排序 sort()

        Collections.sort(list);

        log.info("排序后的集合:{}",list);

 

        //查找 binarySearch();仅支持list集合

        log.info("查找集合中元素5的位置:{}",Collections.binarySearch(list, "5"));

 

        //复制copy();目标集合必须先初始化且比源集合长度长(java.lang.IndexOutOfBoundsException)

        List<String> destList = new ArrayList<>(Arrays.asList(new String[list.size()]));

        Collections.copy(destList,list);

        log.info("copy后目标集合:{}",destList);

 

        //替换 replaceAll()

        Collections.replaceAll(list,"6","9");

        log.info("集合元素6替换9:{}",list);

 

        //填充 fill()

        Collections.fill(destList,"99");

        log.info("填充目标集合后:{}",destList);

 

        //反转 reverse()

        Collections.reverse(list);

        log.info("反转后集合:{}",list);

 

        //指定不可变集合 unmodifiable* (java.lang.UnsupportedOperationException)

        List<String> unmodifiableList = Collections.unmodifiableList(list);

        log.info("不可变集合:{}",unmodifiableList);

 

        //同步集合 synchronized*;在迭代时,用户必须在返回的列表上手动同步

        List<String> synchronizedList = Collections.synchronizedList(list);

        synchronized (synchronizedList) {

            Iterator i = synchronizedList.iterator(); // Must be in synchronized block

            while (i.hasNext())

                System.out.print(i.next()+"->");

            System.out.println();

        }

        log.info("同步集合:{}",synchronizedList);

    }

      

Comparable 与 Comparator

  • Comparator 和 Comparable都是Java中的比较器接口,都是用来实现对一个自定义的类进行排序
  • 不同的是实现Comparable接口是定义在类的内部,比较代码需要嵌入类的内部结构中
  • Comparator 实现在类的外部,单独实现第一个比较器,不需要对原来的类进行结构上的变化,属于无侵入式的
  • Comparator是函数式接口其内部已经提供部分方法(reversed(),thenComparing(),naturalOrder(),……)

Comparable,Comparator测试Demo

/**

     * 比较

     *   comparable:接口;java.lang包;类内部必须实现

     *   comparator:接口; java.util包;自己实现 ; 函数式接口@FunctionalInterface

     */

    @Test

    public void testCMP(){

        List<Student> list = new ArrayList<>();

        list.add(new Student(2,27,"张一"));

        list.add(new Student(1,20,"李二"));

        list.add(new Student(3,25,"王三"));

        list.forEach(s-> System.out.println(s));

 

        System.out.println("按照自然维度排序-comparable");

        Collections.sort(list);

        list.forEach(s-> System.out.println(s));

 

        System.out.println("自定义按照年龄比较器排序-comparator");

        /*Collections.sort(list, new Comparator<Student>() {

            @Override

            public int compare(Student o1, Student o2) {

                //按照年龄排序

                return Integer.compare(o1.getAge(),o2.getAge());

            }

        });*/

 

        Collections.sort(list,Comparator.comparingInt(Student::getAge));

 

        list.forEach(s-> System.out.println(s));

    }

 

    @ToString

    @Setter

    @Getter

    class Student implements Comparable {

        public int id;

        public int age;

        public String name;

 

        public Student(int id, int age, String name) {

            this.id = id;

            this.age = age;

            this.name = name;

        }

        @Override

        public int compareTo(Object o) {

            Student stu = (Student) o;

            //按照id比较大小

            return Integer.compare(id, stu.getId());

        }

    }

             

集合遍历方式

常见的遍历方式

  • for循环 : 针对可随机访问的集合;可定位当前索引位置;遍历时不可修改集合元素(ConcurrentModificationException)
  • forEach(增强for循环)  : 底层使用Iterator;不支持remove()方法
  • Iterator : 集合通用的迭代器; 只支持向后遍历 ; 支持唯一安全的方式remove()删除
  • ListIterator : 针对list集合的遍历器;还支持向前遍历;提供add(),set(),remove()方法;可定位索引位置
  • java8处理 : 形式如for循环(待进一步求证)

集合遍历demo

/**

     * 集合的遍历

     * for循环: 针对可随机访问的集合;可定位当前索引位置;遍历是不可修改集合元素(ConcurrentModificationException)

     * forEach(增强for循环): 底层使用Iterator;不支持remove()方法

     * Iterator : 集合通用的迭代器; 单向移动只支持向后遍历 ;

     *                支持唯一安全的方式remove()删除迭代器返回的最后一个元素并且是

     * ListIterator : 针对list集合的遍历器;双向移动支持向前遍历;提供add(),set(),remove()方法;可定位索引位置

     * java8流式处理 : lambda表达式如for循环;stream如Iterator

     */

@Test

    public void testIterator() {

        List<String> list = new ArrayList<>(Arrays.asList("1", "2", "3", "a", "b"));

        Set<String> set = new HashSet<>(Arrays.asList("1", "2", "3", "a", "b"));

        System.out.println("初始化list集合:" + list);

        System.out.println("初始化set集合:" + set);

 

        //for循环遍历

        System.out.print("for循环遍历list集合:");

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

            System.out.print(list.get(i) + "->");

            if (i == list.size() - 1)

                System.out.println();

        }

 

        //Iterator遍历

        System.out.print("for循环遍历set集合:");

        Iterator<String> iterator = set.iterator();

        while (iterator.hasNext()) {

            String next = iterator.next();

            System.out.print(next + "->");

            if("1".equals(next)){

                iterator.remove();

            }

        }

        System.out.println();

 

        //forEach

        System.out.print("forEach循环set集合:");

        for (String str : set) {

            System.out.print(str + "->");

        }

        System.out.println();

 

        //ListIterator

        ListIterator<String> listIterator = list.listIterator();

 

        System.out.print("listIterator向后遍历元素的 索引|元素:");

        while (listIterator.hasNext()){ //向后遍历

            System.out.print(

                    +listIterator.nextIndex()+"|"+listIterator.next()+"->");

        }

        System.out.println();

 

        System.out.print("listIterator向前遍历元素的 索引|元素:");

        while (listIterator.hasPrevious()){ //先前遍历

            System.out.print(listIterator.previousIndex()+"|"+listIterator.previous()+"->");

        }

        System.out.println();

 

        //遍历时add(),set(),remove()

        while(listIterator.hasNext()){

            String next = listIterator.next();

            System.out.print("遍历集合的元素:"+next);

 

            //遇到a新增一个aa

            if("a".equals(next)){

                listIterator.add("aa");

                System.out.print("...->新增aa");

            }

 

            //遇到b调整成m

            if("b".equals(next)){

                listIterator.set("m");

                System.out.print("...->b替换成m");

            }

 

            //删除字符串"1"

            if("1".equals(next)){

                listIterator.remove();

                System.out.print("...->删除1");

            }

            System.out.println();

        }

 

        //遍历结束后打印list集合

        System.out.println("list集合:" + list);

 

        //java8处理(底层for循环)

        System.out.print("java8 Lambda 表达式遍历集合:");

        list.forEach(s->System.out.print(s+"->"));

        System.out.println();

 

        System.out.print("java8 stream+Lambda 表达式遍历集合:");

        list.stream().forEach(s->System.out.print(s+"->"));

        System.out.println();

    }

      

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值