Java进阶学习笔记

一、集合

单列集合  双列集合

单列集合 collection

下图红色为接口 蓝色为实现类

Java进阶学习笔记_第1张图片

Java进阶学习笔记_第2张图片

1、list(可重复、有索引)

  • ArrayList

  • LinkedList

  • vector

2、Set(不重复、无序、无索引)

  • HashSet(无序、不重复、无索引)

    • LinkedHashSet(有序、不重复、无索引)

  • TreeSet(可排序 不重复 无索引)

3、list

遍历

迭代器遍历:在遍历的过程中需要删除元素,请使用迭代器

列表迭代器:在遍历的过程中需要添加元素,请使用列表迭代器

增强for遍历、Lambda表达式:仅仅想遍历,那么使用增强for或Lambda表达

普通for:如果遍历的时候想操作索引,可以用普通for2)

// 迭代器遍历
        Iterator it = s.iterator(); // 获取迭代器
        while (it.hasNext()){   // 判断是否为空
            String str = it.next(); // 获取元素 并向后移动指针
            System.out.println(str);

        }
        
        // 增强for
        for (String str : s) {
            System.out.println(str);
        }
        // lamada 表达式
        s.forEach(str ->System.out.println(str));
1)ArrayList

ArrayList 低层是数组

  • 利用空参创建的集合,在低层创建一个默认长度为0的数组
  • 添加第一个元素时,低层会创建一个新的程度为10 的数组
  • 存满时,会扩容1.5倍
  • 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准
2)LinkedList

低层数据结构是双链表,查询慢,增删快,但是如果操作的是首尾元素,速度也是几块的

提供了许多首尾操作的API(添加 、 获取、删除首尾元素)

4)Vector
【1】栈  Stack

实现类有ArrayDeque(基于数组的双端队列) 和 LinkedList(基于双链表)​​​​​​

方法

  1. 入栈(推入元素):

    push(E e):将元素推入栈顶,等效于 addFirst(E e)
  2. 出栈(弹出元素):

    pop():弹出栈顶元素,等效于 removeFirst()
  3. 获取栈顶元素:

    peek():获取栈顶元素,但不将其从栈中移除。
  4. 判断栈是否为空:

    isEmpty():如果栈为空,则返回 true;否则,返回 false
  5. 获取栈的大小:

    size():返回栈中元素的数量。
【2】队列 Queue

实现类有ArrayDeque(基于数组的双端队列) 和 LinkedList(基于双链表)​​​​​​

offer() 入队

poll() 出队

peek() 获取对顶元素  等方法用于队列操作。

4 、Set

特点:

  • 无序:存取顺序不一致
  • 不重复:可以去除重复
  • 无索引:没有带索引的方法,所以不能使用普通for循环,也不能通过索引来获取元素
1) HashSet
哈希值

可以理解为:对象的整数表现形式

特点:

  • 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
  • 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
  • 小部分情况下,可能哈希值一样(哈希碰撞)
HashSet底层原理

(数组+链表形式)

HashSet利用HashCode 和Equal方法进行去重

  1. 创建一个默认长度16,默认加载因为0.75的数组,数组名table
  2. 根据元素的哈希值跟数组的长度计算出应存入的位置
  3. 判断当前位置是否为null,如果是null直接存入
  4. 如果位置不为null,表示有元素,则调用equals方法比较属性值
  5. 一样:不存不一样:存入数组,形成链表

如果集合中存储的是自定义对象,必须要重写HashCode 和Equal方法

HashSet去重练习
        // HashSet 去重
        Student s1 = new Student("aaa",12);
        Student s2 = new Student("bbb",12);
        Student s3 = new Student("ccc",12);
        Student s4= new Student("ddd",12);
        Student s5 = new Student("aaa",12);

        // 添加集合
        Set hs = new HashSet();
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);
        hs.add(s5);

        // 打印集合
        System.out.println(hs);
2)LinkedHashSet

特点:

  • 有序、不重复、无索引
  • 这里的有序指的是保证存储和取出的元素顺序一致
  • 原理:底层数据结构依然是哈希表,只是内个元素有额外的多了一个双链表机制记录存储的顺序
3)treeSet
特点
  • 不重复、无索引、可排序
  • 可排序:按照元素的默认规则(由小到大)排序
  • treeSet集合底层是基于红黑树的数据结构实现排序的, 增删改查性能都较好

练习

        /*
        * treeSet 存储整数并进行排序
        * */
        // 创建集合对象
        TreeSet ts = new TreeSet<>();

        ts.add(4);
        ts.add(1);
        ts.add(3);
        ts.add(2);
        ts.add(5);

        // 打印输出默认排序
        System.out.println(ts);

        // 迭代遍历
        Iterator it = ts.iterator();
        while (it.hasNext()){
            Integer i = it.next();// jdk5 以后Integer 和 int 可相互转化
            System.out.println(i);

        }

        // 增强for遍历
        for (Integer t : ts) {
            System.out.println(t);
        }

        // lambda遍历
        ts.forEach( i -> System.out.println(i));
treeSet的两种比较方式 
方式一:

默认排序/自然排序:Javabean类实现Comparable接口指定比较规则【重写compareTo方法】

Java进阶学习笔记_第3张图片

方式二

比较器排序:创建TreeSet对象时候,传递比较器Comparator指定规则

如果两种方式同时存在,以方式二为准

5、单列集合使用场景总结

Java进阶学习笔记_第4张图片


 双列集合

  • 一次添加一对元素  键值对
  • 键不能重复,值可以重复
  • 键和值一一对应的,每一个键中能找到自己对应的值

Java进阶学习笔记_第5张图片

1、Map常见API

Map是双列集合的顶层接口,他的功能是全部双列集合都可以继承使用的

Java进阶学习笔记_第6张图片

Map集合常用方法: 
public static void main(String[] args) {
        // 创建Map集合对象
        Map m = new HashMap<>();
        // put 方法细节:
        /*
        * 添加/覆盖
        * 在添加数据的时候,如果键不存在,那么直接把键值对添加到Map集合中,方法返回null
        * 在添加数据时,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回
        * */
        m.put("1","111");
        m.put("2","222");
        m.put("3","333");

        // 打印集合
        System.out.println(m);
        // 判断是否包含
        boolean containsKey = m.containsKey("1");
        System.out.println(containsKey);
        boolean containsValue = m.containsValue("1");
        System.out.println(containsValue);

        // 求集合的长度
        int size = m.size();
        System.out.println(size);

        // 删除
        String remove = m.remove("1");
        System.out.println("删除的值为:" + remove);

        System.out.println("删除后的集合为:" + m);

        // 清空集合
        m.clear();
    }
Map的遍历方式
  • 键找值
  • 键值对
  • Lambada表达式
        // 遍历法一 键找值
        // 1.获取所有的键,把这些键放到一个单列集合中
        Set keys= m.keySet();
        // 2.遍历单列集合,得到每一个键
        for (String key : keys) {
            // 3.利用Map集合中的键获取对应的值 get
            String value = m.get(key);
            System.out.println(key + "=" + value);
        }

        // 遍历法二:键值对
        // 1. 通过一个方法获取所有键值对
        Set> entries = m.entrySet();
        // 2.遍历entries集合,得到每一个键和值
        for (Map.Entry entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }

        // 遍历法三:Lambada
        /*m.forEach(new BiConsumer() {
            @Override
            public void accept(String key, String value) {
                System.out.println(key + "=" + value);
            }
        });*/
        m.forEach((key, value) ->System.out.println(key + "=" + value));

2、HashMap

不重复、无索引

HashMap是Map里面的一个实现类 

1.HashMap底层是哈希表结构的

2.依赖hashCode方法和equals方法保证键的唯一

3.如果键存储的是自定义对象,需要重写hashCode和equals方法

   如果值存储自定义对象,不需要重写hashCode和equals方法

https://blog.csdn.net/weixin_44915226/article/details/12390735

常用方法整理:
1.put(Object key, Object value) //添加键值对
2.putAll(Collection c) //添加指定的映射关系到目标映射关系
3.get(Object key) //根据键来获取对应的值
4.getOrDefault(Object key, V defaultValue) //map中存在key则使用对应的value,否则使用defaultValue
4.containsKey(Object key) //是否有指定key的映射
5.containsValue(Object value) //是否有指定value的映射
6.remove(Object key) //删除该键值对
7.values() //返回所有值,返回形式为Collection
8.isEmpty() //测试映射是否为空
10.size() //返回大小

3、LinkedHashMap

  • 由键决定:有序、不重复、无索引(有序指的是保证存储和取出的元素顺序一致)
  • 原理:低层数据结构依然是哈希表,知识每个键值对元素又额外的多了一个双链表机制记录存储的顺序
// 创建集合
LinkedHashMap lhm = new LinkedHashMap<>();

// 添加元素
lhm.put("c",1);

// 打印集合
Systen,out.println(lhm);
4、TreeMap
  • 跟TreeSet低层原理一样,都是红黑树结构
  • 不重复、无索引、可排序
  • 可排序:对键进行排序
  • 注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则


二、数据结构

1、栈

先进后出、后进先出

2、队列

先进先出、后进后出(排队)

3、数组

查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同(元素在内存中是连续存储的

删除效率低:要将原始数据删除,同时后面每个数据前移

添加效率极低:添加位置后的每个数据后移,再添加元素

4、链表

Java进阶学习笔记_第7张图片

链表中的结点是独立的对象,在内存中是不连续的,每个结点包含数据值和下一个结点的地址。

链表查询慢,无论查询哪个数据都要从头开始找

链表增删比较快

双向链表

5、树

父节点  左子结点  右子节点

1)普通二叉树(存储无规则)

2)二叉查找树(左小右大):

又称二叉排序树 或者 二叉搜索树

特点:
  • 每一个节点上最多有两个子节点
  • 任意节点左子树上的值都小于当前节点
  • 任意节点柚子树上的值都大于当前节点
添加节点规则
  • 小的存左边
  • 大的存右边
  • 一样的不存
二叉树的遍历
前序遍历

根左右

中序遍历【掌握 遍历的顺序为从小到大】

左根右

后序遍历

左右根

层序遍历

一层一层的去遍历

二叉树的弊端

可能会在树的一边

3)平衡二叉树(任意节点左右子树高度不超过1)

本质也是二叉查找树

旋转触发机制:二叉树平衡破坏

平衡二叉树旋转机制
① 左旋

确定支点:从添加的节点开始,不断的往父节点找不平衡的节点

② 右旋

确定支点:从添加的节点开始,不断的往父节点找不平衡的节点

步骤

以不平衡的点作为支点

就是将根节点的左侧往右拉

原先的左子节点变成新的父节点,并把多余的右子节点出让,给已经降级的根节点当左子节点

③ 平衡二叉树需要旋转的情况

左左:当根节点左子树的左子树有节点插入,导致二叉树不平衡    一次右旋

左右:当根节点的左子树的柚子树有节点插入,导致二叉树不平衡   先局部左旋 整体右旋

右右:当根节点的右子树的右子树有节点插入,导致二叉树不平衡    一次左旋

右左:当根节点右子树的左子树有节点插入 ,导致二叉数不平衡    先局部右旋,在整体左旋

6、红黑树 —平衡二叉B树

  • 是一个二叉查找树:
  • 但是不是高度平衡的
  • 条件:特有的红黑规则

Java进阶学习笔记_第8张图片

红黑树添加节点的规则

添加的节点默认是红色的

Java进阶学习笔记_第9张图片

你可能感兴趣的:(java,开发语言)