Collection接口下的集合

数组

	数组、集合都是对多个数据进行存储操作的,简称为容器,
	PS:这里的存储指的是内存层面的存储,而不是持久化存储
数组:特点
	数组一旦确定了长度,那么长度就确定了,不可以更改。
	数组一旦声明了类型以后,数组中只能存放这个类型的数据,数组中只能存放同一种类型的数据。
	缺点:
		数组长度一旦指定,那么长度就被确定了,不可以更改。
		删除、增加元素,效率低
		数组中实际元素的数量是没有办法获取的,没有提供对应的方法或者属性来取。
		数组存储:有序,可重复,对于无序的,不可重复的数组不能满足要求
	数据结构图	![在这里插入图片描述](https://img-blog.csdnimg.cn/adca3047ed3c44ce8d5557a0b2a46ecc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aO55L2w5aSn5aSa,size_20,color_FFFFFF,t_70,g_se,x_16)

Jdk1.8:ArrayList源码

在这里插入图片描述
底层是一个object[]数组,size数组中的有效长度,
ArrayList obj=new ArrayList()
调用空构造器
在这里插入图片描述
在jdk1.8在调用空构器的时候,底层elementData数组的初始化为{}
在这里插入图片描述
在这里插入图片描述

jdk1.7:给数组赋值为一个空数组
底层数组,在调用构造器的时候,数组长度初始化为10,扩容的时候扩展为原数组的1,5倍
jdk1.8:底层数组,在调用构造器的时候,底层数组长度为{},在调用add方法以后,底层数组才重新赋值为新数组,新数组的长度为10,节省了内存,在add后才创建了为10的数组

Vector

在这里插入图片描述
底层也是一个数组和一个int类型的elementCount有效长度

Vector v=new Vectou()调用构造器
默认初始值为10
在这里插入图片描述
ArrayList和Vector的联系和区别:
联系:底层都是数组的扩容,查询效率高,删除和插入效率低
区别:Arraylist的底层扩容为1.5倍,线程不安全,效率高,Vector的底层扩容为两倍,线程安全,效率低

LinkList

LinkList常用方法:
增加:addFirst() addLast() offer() offerFirst() offerLast()
删除:poll() pollFirst() pollLast() remove() removeLast()
修改:
查看:element() getFirst() getLast() indexOf() LastindexOf() peek()
判断:
遍历方式:
1、普通的for循环
2、增强for循环
3、利用迭代器
ArrayList数据结构:
物理结构:紧密结构
逻辑结构:线性表(数组)
LinkList数据结构:
物理结构:跳转结构
逻辑结构:线性表(链表)
模仿写一个linklist

package com.example.demo.service.impl;

public class Node {
    private Node pre;
    private Object obj;
    private Node next;

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "pre=" + pre +
                ", obj=" + obj +
                ", next=" + next +
                '}';
    }
}
package com.example.demo.service.impl;

public class MyLinkList {
    //链表中一定有一个首节点
    private Node first;
    //链表中一定有一个尾节点
    private Node last;
    //计数器
    int count;
    //提供一个构造器
    public MyLinkList(){}
    public void add(Object o){
        if (first==null){
            Node node = new Node();
            node.setPre(null);
            node.setObj(o);
            node.setNext(null);
            //当前链中第一个变成n
            first=node;
            //当前链中最后一个节点变成n
            last=node;

        }else{
            Node node = new Node();
            node.setPre(last);//n的上一个节点一定是当前链中的最后一个last
            node.setObj(o);
            node.setNext(null);
            //当前链表中的最后一个节点的下一个元素要指向n
            last.setNext(node);
            //将当前链表的最后一个一个节点变成n
            last=node;

        }
        //链中元素的数量加一
        count++;

    }
    public int getsize(){
        return count;
    }
    //根据索引获得元素
    public Object get(int index){
        Node n=first;
        for(int i=0;i<index;i++){
            n=n.getNext();
        }
        return n.getObj();
    }
}
class Test{
    public static void main(String[] args) {
        MyLinkList myLinkList = new MyLinkList();
        myLinkList.add("aa");
        myLinkList.add("bb");
        myLinkList.add("cc");
        System.out.println(myLinkList.getsize());
        System.out.println(myLinkList.get(2));
    }
}

LinkList源码分析:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
	
    transient int size = 0; //集合中的元素数量

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first; //链表的首节点

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
	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;
        }
    }
    transient Node<E> last;//链表的末节点

    /**
     * Constructs an empty list.
     */
     空构造器
    public LinkedList() {
    }
    //在链表中添加一个元素
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    //添加元素e
        void linkLast(E e) {
        final Node<E> l = last;//将链表中的last节点给l,如果是第一个元素的话l为null
        final Node<E> newNode = new Node<>(l, e, null);
        //将链表的last节点指向新创建的对象
        last = newNode;
        //如果添加的是第一个元素
        if (l == null)
            first = newNode;//将链表的first节点指向尾新节点
        else//如果不是第一个节点
            l.next = newNode;
        size++; //集合中元素的数量
        modCount++;
    }

Node<E> node(int index) {
        // 如果index在链表的前半段,那么从前往后找

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {//如果index在链表的后半段,从后往前找
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

iterator() Iterator Iterable关系

在这里插入图片描述

Collection的set接口

hashSet() 特点:无序切不可重复
疑问点:
1、数组的长度是多少
2、数组的类型是什么
3、hashCode和equal真的使用了吗?
4、底层表达式是什么?
5、同一个位置的数据向前放,还是向后方
6、放入数组中的数据,是直接放的吗?是否封装为对象了?
实现类:LinkedHashSet:唯一,有序(按照输入进行输出)
其实就是在hashSet的基础上,多了一个总链表,这个总链表将放入的元素串在一起,方便有序和一个表达式计算在数组中的位置。
比较器的使用
1、int类型的比较:将比较的数据做差,然后返回一个int类型的数据,将这个返回的数据按照>0 =0 <0做比较
2、比较String类型的数据:String实现了一个comparable接口,这个接口有一个抽象方法cpmpareTo,String重写了这个方法。
3、比较double类型的数据:Double实现了一个comparable接口,这个接口有一个抽象方法cpmpareTo,Double重写了这个方法。
4、比较类的时候只需要继承comparable接口,内部重写compareTo()接口
5、外部比较器,优点大于内部比较器,可以灵活的写。
TreeSet
特点:唯一、无序、按照升序进行排列。
原理:底层二叉树(数据结构中的一个逻辑结构)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值