Fork me on GitHub

JavaSE Day16 集合 list set

JavaSE Day16 集合 list set


比较器总结

基本数据类型,自然升序

应用数据类型,自然升序排序

字符串: 查看源码,字典排序,

不等,对应位的字符不等 或者 长度不等

自定义类

用重写的方法compareTo排序;
返回的是负数时,需要调换位置;

集合

容器,位于util包中

集合的继承关系,实现类等

集合和数组的区别

  1. 数组存储 基本类型和引用;
    集合 只能存储 引用。
  2. 数组 长度是固定的;
    集合 长度是不固定的。数据结构(数据的组织形式);消耗大

Collection 接口

特点:数据可以重复,无序

List接口

特点:数据可以重复,有序,线性排列;

实现类

  1. ArrayList: 数据结构是 数组
  2. Verctor: 数据结构也是数组,不建议使用;
  3. LinkedList:数据结构;链表

实现类比较

ArrayList:(出现晚一点)

  1. 底层是数组,默认初始容量为10,
  2. 扩容为:0.5倍扩容,重新创建一个数组,拷贝原始数组到新数组中;
  3. System.arraycopy 效率较高
  4. 性能较高,与verctor比
  5. 线程非安全,速度快,
  6. 可以使用其他类 包装;提高安全性;

Verctor:不常用,和ArrayList基本上一样,

  1. 底层是数组
  2. 遍历快,
  3. 插入和删除慢;
  4. 性能较低,与ArrayList比,
  5. 线程安全,但是慢
  6. 一般不用了;性能太低;
  7. 扩容1倍

LinkedList

  1. 底层是链表
  2. 单向链表
    • Node节点,包含 数据域(值域)和链域(存在下一格元素地址的;)
    • 最后一个元素的存储的地址为null
  3. 双向链表
    • 前驱 数据域 后继,两个链域
    • 前驱存储前一个元素的地址,后继存储后一个元素的存储地址;
  4. 遍历慢,或随机查找某个元素
  5. 插入和删除元素 快;

Collection API

package day16;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class TestCollection {
    public static void main(String[] args) {
        // Collection
        // 创建一个集合
        Collection<String> c = new ArrayList<>();
        ArrayList<String> c3 = new ArrayList<>();
        // 判断集合是否为空,集合元素的个数
        System.out.println(c.isEmpty());//true
        // 添加
        c.add("aa");
        c.add("bb");
        c.add("cc");
        c.add("ddd");
        // 打印集合
        System.out.println(c);
        // 查看源码
        System.out.println(c3.toString());
        System.out.println(c.isEmpty());// false
        // 添加的集合中的元素的个数;
        System.out.println(c.size());
        //
        Collection<String> c1 = new ArrayList<>();
        c1.add("ee");
        c1.add("ff");
        // 把参数集合中的所有元素,添加到当前集合中,当前集合只要发生了改变,就是true
        c.addAll(c1);
        System.out.println(c);

        // 删除 参数指定的元素,只要当前集合发生了改变,返回true;
        c.remove("bb");
        System.out.println(c);
        // 删除指定参数集合中的所有元素;
        c.removeAll(c1);
        System.out.println(c);
        // 按照指定条件删除
        /*c.removeIf(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 3;
            }
        });
        */
        c.removeIf(s -> s.length() == 3);
        System.out.println(c);
        // 参数指定的元素在集合中是否包含,包含就是true
        System.out.println( c.contains("cc"));
        // 参数集合中的所有元素 在当前集合是否包含,包含就是true
        System.out.println(c.containsAll(c1));
        //                    把一个字符串数组 转换成集合
        // 转换的集合 是Arrays的静态内部类ArrayList,
        // 是一个固定长度的集合,不能像集合中添加或删除元素
        List<String> c2 = Arrays.asList(new String[]{"ee","ff"});

        //
        c.addAll(c2);
        System.out.println(c);
        System.out.println(c.containsAll(c1));

        // 集合转数组
        Object[] obj = c.toArray(new Object[10]);// 默认为0,如果多了,多的元素就是null;
        System.out.println(Arrays.toString(obj));


        String[] str = c.toArray(new String[14]);
        System.out.println(Arrays.toString(str));

        // 清空元素
        c.clear();
        System.out.println(c.isEmpty());
        System.out.println(c.size());


    }
}

ArrayList API

package day16;

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

public class TestList02 {
    public static void main(String[] args) {
        // List有顺序,按元素的添加的顺序,
        List<String> list = new ArrayList<>();
        list.add("aa");//索引0
        list.add("bb");//1
        list.add("cc");//2
        list.add("dd");
        System.out.println(list);
        // 可以向索引位置添加元素
        list.add(1,"xx");
        System.out.println(list);
        // 获得索引出的元素
        System.out.println(list.get(1));
        // 用第二参数元素,替换索引出的元素
        list.set(1,"yy");
        System.out.println(list);
        //
        list.add("aa");
        System.out.println(list);
        // 返回参数元素 在当前集合中 第一次出现的位置索引
        System.out.println(list.indexOf("aa"));
        // 返回参数元素 在当前集合中 最后一次出现的位置索引
        System.out.println(list.lastIndexOf("aa"));
        // 取子集,[起始位置,终止) 取到终止的前一位;
        System.out.println(list.subList(1,4));
        // 排序
        System.out.println(list);
        // 参数是 Comparator类型的比较器;
        // 参数是 null,会按照Comparable的方式自然升序排序;
        list.sort(null);
        System.out.println(list);
        list.sort(String::compareTo);
        // list.sort((s1,s2)->s2.compare(s1))
        // ;
        System.out.println(list);
    }
}

Iterator API

package day16;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;

public class TestIterator {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        System.out.println(list);
        // 遍历
        // 1. 普通for
        System.out.println("普通for");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("------------------------");
        // 2. 增强for
        System.out.println("增强for");
        for (String s : list
        ) {
            System.out.println(s);
        }
        System.out.println("-------------------------");
        // 3. foreach
        System.out.println("foreach");
        /*
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);// s表示集合的元素
            }
        });
        list.forEach(s -> System.out.println(s));
        */
        list.forEach(System.out::println);
        System.out.println("-------------------------");
        // 4. Stream foreach
        System.out.println("stream foreach");
        list.stream().forEach(System.out::println);
        System.out.println("-------------------------");
        // 5. Iterator 迭代器
        // 获得了一个迭代器
        System.out.println("Iterator 迭代器");
        Iterator<String> i = list.iterator();
        /*System.out.println(i.next());
        System.out.println(i.next());
        // 删除的最近一次next(),所访问的元素
        i.remove();
        System.out.println(i.next());
        System.out.println(list);*/
        while (i.hasNext()) {
            System.out.println(i.next());
            //list.add("abc");
            // 不能添加,会报错 穿行报错 java.util.ConcurrentModificationException
        }
        //System.out.println(i.next());
        // 超过列表长度 报错 java.util.NoSuchElementException
        System.out.println("-------------------------");

        // 6. ListIterator
        ListIterator<String> li = list.listIterator();
        while (li.hasNext()) {
            System.out.println(li.next());// 为什么不带有hello
            li.add("hello");
        }
        // 向前遍历
        while (li.hasPrevious()) {
            System.out.println(li.previous());
        }
        System.out.println("-------------------------");
        // 7. Iterator foreachremining 迭代器的迭代方法
        Iterator<String> i1 = list.iterator();
        i1.forEachRemaining(System.out::println);

        System.out.println("-------------------------");
        System.out.println("-------------------------");


    }
}

Set 接口

特点:存储的数据唯一,无序

  1. 直接实现类,hashSet,linkedHashSet,
  2. sortedSet接口:排序
  3. NavigableSet接口:精确运算
  4. NavigableSet和sortedSet的实现类: TreeSet

HashSet:

  1. 底层结构是Hash

  2. 特点

    • 哈希表
    • 唯一,hashcode,equals,效率高
    • 无序
    Set<String> set = new HashSet<>();
        set.add("aa");
        set.add("bb");
        set.add("cc");
        System.out.println(set);
        boolean bool = set.add("aa");
        System.out.println(set);
        System.out.println(bool);// false 表示添加失败
    
  3. 哈希算法:

  4. 哈希表:将一组关键字映射到地址集上;

  5. 注意:
    首先hashCode()算出位置,存储元素,如果哈希冲突(算出的位置值,与之前存储过的元素的哈希值一样的,)调用equals判断是否为同一个对象,是同一个,不存储采用旧的值,不同一个可以存储连式存储,节点个数超过8个采用 二叉树存储。

  6. 重写

    • hashCode equals用自己的规则去重;
    • 桶:数组+链表

TreeSet

  1. 底层数据结构是二叉树;
    • 树:是由节点集及连接每对的有向边组成。 二叉树:形结构任意节点不能超过两个孩子。
    • 根节点,枝节点:中间的节点; 叶节点:没有子节点的节点;
    • 中序,左中右的遍历方式,
  2. 自然升序
  3. 自己制定顺序,Comparator,
  4. 必须有排序规则,否则报错,
  5. 当comparable或 comparator 比较为0时,TreeSet认为是一个元素,因此只保存一份;

linkedHashSet

  1. 链表和哈希表
  2. 按照元素的添加的顺序来维护的;
  3. 唯一

TreeSet API

SortedSet<String> set = new TreeSet<>();
        set.add("cc");
        set.add("bb");
        set.add("aa");
        System.out.println(set);
        // 返回排过序的第一个元素,和最后一个元素
        System.out.println(set.first());
        System.out.println(set.last());
        // [起始元素,终止元素) 取子集
        set.subSet("aa","cc").forEach(System.out::println);

额外的知识点 - TreeSet去重(需要重新整理)

TreeSet在存储对象时,一般为了去重都会重写CompareTo方法,但是如果是比较的有2个属性,例如:先按名字排序,如果名字不同就按年龄排序,此时就会出现个别元素无法去重的情况。

posted @ 2018-10-03 00:56  耳_东  阅读(75)  评论(0)    收藏  举报