小王Java学习打卡day12——集合,栈,链表

集合

基本数据结构

  1. 什么数据结构?计算机存储,组织数据(插入,更新,删除,查询)的方式。
    • 意义:可以带来更高的存储或者运行效率。
    • 需求:高效率的检索算法,索引技术。
    • 作用(模拟):存储班级里学生的信息
      • 保存学生信息
      • 修改学生信息
      • 删除学生信息
      • 查询学生信息
  • ​ 开发一个工具类(重复代码-----sun公司已经开发好了)
  1. 需求:假如你是大学程序竞赛的导师,一共有五个参赛名额,1-2个替补。

    • 准备一个数组(5)[0,1,2,3,4,5]
    • 安排五个学生上场比赛
    • 查询某一个学生的位置是几号
    • 替换掉2号位置的学生,换一个学生上场
    • 3号位置作弊,被罚下场,不能安排替补接替、
    • 打印出最后比赛的选手名称
  2. 让F G 都参加比赛(出现了索引越界异常)

//定义一个copy数组的方法
public String[] copy(String[] src,int newLength){
    String[] ret = new String[newLength];
    System.arraycopy(src,0,ret,0,size);
    return ret;
}
  1. 性能分析
    • 大O表示法。表示时间复杂度,专门用于计算性能相关参数
    • 针对我们的比赛,进行性能分析
      • 保存操作:
        • 保存到最后一位,需要一次。
        • 保存到第一个位置,如果当前存在 x 个元素,需要操作 x 次,平均(x+1)/2
      • 查询操作:
        • 根据索引查找,只需要一次
        • 根据名称查,需要x次,平均(x+1)/2
      • 修改操作:
        • 操作一次
      • 删除操作
        • 删除最后一个元素,只需要一次
        • 删除第1个元素,需要 x 次,平均(x+1)/2
  • 数组的结构,查询和修改都特别快,保存和删除都比较慢。
  1. 链表结构(LinkedList)

    • 单项链表(单方向)
    • 双向链表(双方向)

    单项链表

    单向链表就是通过每个结点的指针指向下一个结点从而链接起来的结构,最后一个节点的next指向null。

    image-20220515013710433

单向循环链表

单向循环链表和单向列表的不同是,最后一个节点的next不是指向null,而是指向head节点,形成一个“环”。

image-20220515013756992

双向链表

从名字就可以看出,双向链表是包含两个指针的,pre指向前一个节点,next指向后一个节点,但是第一个节点head的pre指向null,最后一个节点的tail指向null。

image-20220515013827986

双向循环链表

双向循环链表和双向链表的不同在于,第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,也形成一个“环”。而LinkedList就是基于双向循环链表设计的。

image-20220515013856765
  1. 双向链表的性能分析
    • 添加元素:
      • 第一个元素或者最后一个元素,操作一次
      • 中间插入(x+1)/2
    • 删除元素
      • 第一个元素或者最后一个元素,操作一次
      • 中间元素(x+1)/2
    • 查询元素
      • 平均(x+1)/2
    • 修改元素
      • 平均(x+1)/2
  2. 数组结构和链表结构如何选择
    1. 数组
      • 查询和修改都很快
      • 新增和删除较慢
    2. 链表
      • 新增和删除很快
      • 查询和修改较慢
  3. 栈(Stack)先进后出
    • 基于数组实现
    • 规定:最后一个是栈顶,第一个元素是栈底

集合

img

  1. 集合(jdk1.2) 集合类,直接可以使用
  2. 集合框架类统一为我们调用,底层是数据结构
  3. 常用集合类
    • List 列表:按照索引存放,允许元素重复
    • Map映射:键值对,key - value ,不允许key重复,重复就会覆盖
    • Set集合:不按照特定方式存储,不允许重复

Collection 常用方法

//容量大小
int size();
//判断集合是否为空
 boolean isEmpty();
//判断是否包含某个元素
 boolean contains(Object o);
//迭代器
Iterator<E> iterator();
//
Object[] toArray();
//添加元素
 boolean add(E e);
//删除元素
boolean remove(Object o);
//清空
void clear();
//迭代器的使用
Collection c =new ArrayList();
Iterator iterator = c.iterator();
while (iterator.hasNext()){
    Object elt = iterator.next();
}

Vector

  1. 初始容量为10
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, {
    protected Object[] elementData;
    protected int elementCount;
    public Vector() {
        this(10);
    }

    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    } 
}

  1. 底层是object[]数组,引用数据类型
  2. 实现了基本的增删改查
  3. 常用方法
    • add(object obj)增加
    • remove(int index)删除索引位置元素
    • remove(“B”)删除指定元素
    • set(int index, object obj)修改索引位置元素
    • size()返回当前集合中元素长度
    • get(int index)查询具体索引的元素
    • isEmpty()判断当前集合是否为空

Stack 栈结构

栈是属于List下面的数据结构

class Stack<E> extends Vector<E> {

    public Stack() {
    }
    
    //添加元素
    public E push(E item) {
        addElement(item);
        return item;
    }
    
    //查看栈顶对象
    public synchronized E peek() {
        int     len = size();
        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }
    
    //删除栈顶对象,并且返回
    public synchronized E pop() {
        E       obj;
        int     len = size();
        obj = peek();
        removeElementAt(len - 1);
        return obj;

ArrayList

  1. ​ 用来取代Vector类,(Vector是线程安全的,会消耗性能)
  2. 初始化时候,默认给空数组
  3. 调用add方法的时候,采取重新初始化数组(new 新数组的时候,不用就浪费了,用的时候扩容,节约空间)

ArrayList 和 Vector的区别

  1. ​ Vector是线程安全的,ArrayList是线程不安全的

  2. ArrayList 初始化没给容量,add时候才给

  3. 多线程环境也不会去使用Vector(淘汰了),

    ​ Collection collection = Collections.synchronizedCollection(arrayList);给ArrayList加锁

  4. 擅长 查询和更新

LinkedList 链表

  1. 是一个双向链表

    public class LinkedList<E>
     	transient int size = 0;
        transient Node<E> first;
        transient Node<E> last;
    
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
    
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    
  2. 非线程安全的

  3. 擅长 保存和删除

Set

HashSet

  1. ​ 特点

    • 不允许重复
    • 不会记录元素 的添加顺序(使用hashCode())
  2. 源码分析

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
    
  3. 如果我们需要将自定义的对象存到hashset里面去,去自动生成hashCode 和 equals

LinkedHashSet

  1. 特点

    • 不允许重复
    • 汇集了元素添加顺序
  2. 底层源码

    • 实现了hashset
      rn map.put(e, PRESENT)==null;
      }

    public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
    }

    
    
    
    
  3. 如果我们需要将自定义的对象存到hashset里面去,去自动生成hashCode 和 equals

LinkedHashSet

  1. 特点
    • 不允许重复
    • 汇集了元素添加顺序
  2. 底层源码
    • 实现了hashset
    • 使用的hashMap,使用了链表结构,保证了元素的添加顺序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值