Java api05(collection集合 list set queue 底层实现原理 数据结构二叉树)(文字配图)

集合:
Collection(I) + Map(I)
Collection(I):
|- List(I) - 顺序结构
|- ArrayList© - 数组
|- LinkedList© - 链表
|- Vector© - 数组

|- Set(I) - 散列结构 -> Map(I)
|- SortedSet(I)
|- TreeSet©
|- hashSet©

|- Queue(I) - 队列
|- Dueque(I)
|-LinkedList©

List集合 - 顺序结构
1.List集合的特点
a.List集合是顺序结构,所以是有序列表,可以是用index
b.List集合允许有重复值
c.List集合允许有null值

2.特有方法(带有index)
add(int index, E element)
addAll(int index, Collection<? extends E> c)
set(int index, E element)
subList(int fromIndex, int toIndex)
remove(int index)
get(int index)

3.实现类
ArrayList©
底层实现:数组
底层数据结构:数组
特点:
优点: 查询速度很快(因为有连续的下标,可以根据下标进行查询)
缺点:
a.插入/删除很慢的
b.顺序结构需要连续的物理空间
导致空间的使用率非常低

package api05.Collection.list;

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

/*
    List集合
 */
public class ListDemo01 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("1");
        list.add("1");
        list.add("2");
        list.add("4");
        System.out.println(list);

        //subList
        //前包含后不包含
        List sub = list.subList(0, 2);
        System.out.println(sub);

        //sub新集合
        sub.add("张三");
        System.out.println(sub);

        //原集合有没有包含 张三
        //[1, 1, 张三, 2, 4]
        //原集合 和 子集合共用同一块内存空间
        System.out.println(list);
    }
}

package api05.Collection.list;

import java.util.ArrayList;
import java.util.LinkedList;

/*
    ArrayList和LinkedList的效率对比
 */
public class ListDemo02 {
    public static void main(String[] args) {
        ArrayList arr = new ArrayList();
        LinkedList linked = new LinkedList<>();
        for (int i = 0; i < 5000000; i++) {
            arr.add("i" + i);
            linked.add("i"+i );
        }
        //查询 - ArrayList
       /* long time1 = System.currentTimeMillis();
        arr.get(0);
        long time2 = System.currentTimeMillis();
        linked.get(0);
        long time3 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time2 - time1));
        System.out.println("linked查询效率:" + (time3 - time2));

        //从中间查
        long time4 = System.currentTimeMillis();
        arr.get(2500000);
        long time5 = System.currentTimeMillis();
        linked.get(2500000);
        long time6 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time5 - time4));
        System.out.println("linked查询效率:" + (time6 - time5));

        //从尾部查询
        long time7 = System.currentTimeMillis();
        arr.get(4999999);
        long time8 = System.currentTimeMillis();
        linked.get(4999999);
        long time9 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time8 - time7));
        System.out.println("linked查询效率:" + (time9 - time8));
        */

        //插入 - LinkedList快
        long time1 = System.currentTimeMillis();
        arr.add(0,"1");
        long time2 = System.currentTimeMillis();
        linked.add(0,"1");
        long time3 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time2 - time1));
        System.out.println("linked查询效率:" + (time3 - time2));

        //从中间查
        long time4 = System.currentTimeMillis();
        arr.add(2500000,"1");
        long time5 = System.currentTimeMillis();
        linked.add(2500000,"1");
        long time6 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time5 - time4));
        System.out.println("linked查询效率:" + (time6 - time5));

        //从尾部查询
        long time7 = System.currentTimeMillis();
        arr.add(4999990,"1");
        long time8 = System.currentTimeMillis();
        linked.add(4999990,"1");
        long time9 = System.currentTimeMillis();
        System.out.println("arr查询效率:" + (time8 - time7));
        System.out.println("linked查询效率:" + (time9 - time8));

    }
}

LinkedList©: 双向链表
1)底层实现:Node节点 -> date(数据) + next(下一个节点的引用)
底层数据结构: 链表
2)特点:
a.链表在内存中是固定顺序的,但是他的物理空间不连续
b.没有下标,只有头节点
c.所有的操作只能从头节点出发
d.头节点 head: 不存数据,只有next
4)优缺点:
优点: 插入/删除操作快
不需要连续的物理空间,所以空间使用率高
缺点: 查询速度,因为只能从头节点或尾节点开始查询

5)特有的方法:
	只要带有first/last
	addFirst(E e) 
	addLast(E e) 
	getFirst() 
	getLast() 
	removeFirst() 
	removeLast() 

Vector©
底层实现:数组
和ArrayList一样
不一样的地方:
Vector加了锁(synchronized),线程安全,效率低

面试题:
ArrayList和LinkedList的区别
1.底层实现区别
2.优缺点的区别

对于插入/删除 单个操作而言 -> linkedList比较快
但是: 先查询,找到要插入/删除的位置的前一个节点
查询 + 插入(删除)
因为没有下标,所以查询非常慢

ArrayList和Vector的区别
1.线程安全分析
2.扩容容量
ArrayList扩容为原容量的1.5倍
Vector扩容为原容量的2倍


Queue(I) - 队列(线性结构)
1)特点:
a.先进先出
b.允许有重复值
2)常用方法:
offer() - 向队列尾部追加元素
peek() - 从队列头部获取元素,但是队列不变
poll() - 从队列头部获取元素,删除元素

3)子接口 - Dqueue(I) - 双端队列/栈
可以根据方法区分是双端队列还是栈
Dqueue中的栈实现:
push() - 压栈
pop() - 弹栈

package api05.Collection.queue;

import java.util.Deque;
import java.util.LinkedList;

/*
    LinkedList作为双端队列实现
    poll - 获取并删除数据

 */
public class LinkedDemo01 {
    public static void main(String[] args) {
        Deque linked = new LinkedList<>();
        //linked.add("张三");

        linked.offer("张三");
        linked.offer("张三");
        linked.offer("张三");
        //Fitst/last
        linked.offerLast("李四");
        linked.offerFirst("lucy");
        System.out.println(linked);


        //获取并删除
        Object poll = linked.poll();
        System.out.println(poll);
        System.out.println(linked);


    }
}

package api05.Collection.queue;

import java.util.Deque;
import java.util.LinkedList;

/*
    LinkedList作为栈实现
     push - 添加
     peek() - 获取但是不删除数据
     pop() - 获取并删除数据
 */
public class LinkedDemo02 {
    public static void main(String[] args) {
       Deque linked = new LinkedList<>();
       linked.push("张三");
        linked.push("李四");
        linked.push("王五");
        System.out.println(linked);

        //获取数据,但是不删除数据
        Object pop = linked.peek();
        System.out.println(pop);
        System.out.println(linked);


        //获取并删除数据 - 出栈(弹栈)
        /*Object pop = linked.pop();
        System.out.println(poll);
        System.out.println(linked);*/




    }
}

队列和栈的原理


Set集合 - 散列表 (没有顺序的集合,不是随机!!!)
1.Set特点
a.无序且唯一
b.使用equals判断元素是否重复
c.Set的物理空间是不连续的

2.实现类
HashSet©:
特点:
a.存储位置不是真正的随机位置,根据HashCode方法计算(决定)最终位置
b.使用equals()判断元素是否重复

存储过程:
  ①.调用自身的hashCode()计算存储位置
  ②.判断该位置上是否存在元素
  ③.如果该位置上存在元素
  	 则使用equals()判断是否相等
  	 如果相等则不存入
  	 如果不相等,则存放到链表末尾

HashSet的存储过程

package api05.Collection.set;

import java.util.HashSet;

public class HashSetDemo01 {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        User u1 = new User(18, "张三");
        User u2 = new User(19, "张三");
        set.add(u1);
        set.add(u2);

        u2.setAge(18);
        System.out.println(set);

        //通过HashSet中的构造方法 - 构建另一个集合
        HashSet newSet = new HashSet(set);
        System.out.println(newSet);
    }
}

package api05.Collection.set;

import java.util.HashSet;

public class HashSetDemo02 {
    public static void main(String[] args) {
        HashSet<User> set = new HashSet<>();
        User u1 = new User(18, "张三");
        User u2 = new User(19, "李四");
        User u3 = new User(18, "张三");
        User u4 = new User(19, "李四");
        set.add(u1);
        set.add(u2);
        set.add(u3);
        set.add(u4);
        System.out.println(set);

    }
}

package api05.Collection.set;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo03 {
    public static void main(String[] args) {
        Set<User> set = new HashSet<User>();
        User u1 = new User(18,"张三");
        User u2 = new User(20,"李四");
        set.add(u1);
        set.add(u2);
        System.out.println(set);

        //修改了u2 的年龄
        u2.setAge(23);
        //删除u2的数据
        set.remove(u2);
        System.out.println(set);

        //将数据修改成原数据 - 用另一个集合进行构建

    }
}

package api05.Collection.set;

import java.util.HashSet;
import java.util.Set;

/*
    Set集合的特点
 */
public class SetDemo01 {
    public static void main(String[] args) {
        //hashSet
        //[how, are, hello, you]
        //物理空间没有顺序 - 无序
        Set set = new HashSet<>();
        set.add("hello");
        set.add("how");
        set.add("are");
        set.add("you");
        System.out.println(set);
        //[how, are, hello, you]
        //特点二: 唯一
        set.add("you");
        set.add("you");
        set.add("you");
        System.out.println(set);
    }
}

package api05.Collection.set;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;

/*
    Comparator自定义排序

        数组的排序方法:Arrays.sort() - 默认使用自然排序
        List:Collections.sort() - 默认使用自然排序
        Set: TreeSet() - 默认使用自然排序
        Map: TreeMap() - 默认使用自然排序

        自然排序: Comparable
            重写 compareTo() -> 比较 o 和 this
        自定义排序: Comparator
            重写 compare() -> o1 和 o2
                后 比 前 -> 倒序
                前 比 后 -> 正序
 */
public class SortedDemo05 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(12);
        list.add(8);
        list.add(55);
        //对List集合进行排序 [8, 12, 20, 55]
        //Collections.sort(list);//默认自然排序
        //自定义排序 Comparator
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                /*return o1 - o2;//正序*/
                return  o2 - o1;//倒序
            }
        });
        System.out.println(list);

//__________________________________
        //使用自定义排序对 TreeSet进行排序
        TreeSet<User> set = new TreeSet(new Comparator<User>() {
            @Override
            public int compare(User o1,  User o2) {
                return o1.getAge() - o2.getAge();
            }
        });

        set.add(new User(18,"lucy"));
        set.add(new User(19,"tom"));
        set.add(new User(20,"tom"));
        System.out.println(set);

    }

}

package api05.Collection.set;

import java.util.TreeSet;

/*
    TreeSet - 排序
 */
public class TreeSetDemo01 {
    public static void main(String[] args) {
        //[4, 7, 8, 11]
        TreeSet<String> tree = new TreeSet();
        //A - 65 a - 97
        tree.add("a");
        tree.add("A");
        tree.add("b");
        tree.add("B");
        System.out.println(tree);

        //ClassCastException - 类型转换异常
        TreeSet<User> tree1 = new TreeSet<>();
        User u1 = new User(18, "lucy");
        User u2 = new User(19, "tom");
        tree1.add(u1);
        tree1.add(u2);
        System.out.println(tree1);
    }
}

package api05.Collection.set;

import java.util.Objects;
//实现Comparable接口 - 可排序
public class User /*implements Comparable<User>*/{
    int age;
    String name;

    public User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public User() {
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) return true;
        if (object == null || getClass() != object.getClass()) return false;
        User user = (User) object;
        return age == user.age &&
                Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }



    /* 如果 return 0 ->
        会认为存进来的所有数据都是一样的,不存入
       如果 o 比 this 大 -> 正数
       如果 o 比 this 小 -> 负数

        this.age - o.age -> 正序
        o.age - this.age -> 倒序
     */
   /* @Override
    public int compareTo(User o) {
        // o 和 this(user)
        *//*return this.age - o.age; 正序 *//*
         if(o.age != this.age){
             return o.age - this.age;
         }
        return o.name.compareTo(this.name);

    }*/

}


二叉树
特点:
a.不允许有重复值
b.永远都是(左在前,右在后)
c.左节点 < 父节点 < 右节点

遍历方式:
先序遍历 - 中左右
后序遍历 - 左右中
中序遍历 - 左中右
二叉树原理

TreeSet©
1)底层实现:二叉树
2)父接口 -> SortedSet(I)
3)特点:
a.用来排序,最常用的是中序遍历
4)TreeSet存储过程:
①.最开始的数据跟根节点比较 - compareTo进行比较
②.如果比根节点大,存储在右边
③.如果比根节点小,存储在左边
④.如果元素一样,则不存入

Comparable 自然排序 和 Comparator 自定义排序(指定比较器)

1)所有的自然排序,底层下都是实现了Comparable接口
2)自然排序 Comparable
重写了compareTo()
比较 obj 和 this 进行对比

数组: Arrays.sort()
List: Collections.sort()
Set: TreeSet()
Map: TreeMap()

3)比较器排序 Comparator
重写了compare()
比较 o1 和 o2

数组: Arrays.sort(new Comparator)
List: Collections.sort(new Comparator)
Set: TreeSet(new Comparator)
Map: TreeMap(new Comparator)

4)结论:
sort方法不指定比较器的时候,需要的元素必须是实现Comparable

sort方法指定比较器,元素不需要实现Comparable

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值