Java:集合框架的简易整体总结

一、概述:

1.什么是Collection?它是集合框架的底层,一般不使用。即:Collection是集合层次结构中的根接口,存储的是一组对象,一般不会使用它去操作集合。

2.集合的三个特点
(1)是否允许有重复元素
(2)是否元素有序【add的顺序和get的顺序是一样的】
(3)是否允许存放null

3.Collection有很多子接口,而其中最重要最常用的就是List/Set/Queue三个子接口,它们分别对父接口的功能做了各自的扩充~

接下来就具体介绍三个重要子接口中的几个重要分类与具体描述~~
注意只介绍常用分类,其他的以后可能会做另一篇的介绍

二、List

1.ArrayList:最常用的存储形式,熟练运用掌握,编码牢记于心~

(1)允许重复元素,是有序的,允许出现空值。 (2)值得注意的是ArrayList的扩容是扩容成1.5倍,底层代码为:

newCapacity = capacity + (capacity>>1)

(3)实现代码:

public class MyArrayList <T>{
    private T []element;
    private int size;
    private final static int defaultCapacity = 10;

    public MyArrayList(){
        this(defaultCapacity);
        this.size = 0;
    }

    public MyArrayList(int Size){
        this.element = (T[])new Object[Size];
        this.size = 0;
    }

    public boolean isEmpty(){
         return size ==0;
    }

    public boolean isOverBoard(){
        if(this.element.length == size)
            return true;
        else
            return false;
    }

    public void growUp(){
         this.element= Arrays.copyOf(this.element,this.element.length+1);
    }

    public void add(T value){
        if(isOverBoard())
            growUp();
        element[size] = value;
        size++;

    }

    public void remove(T value) {
        try {
            checkRemove();
            checkValue(value);
        } catch (NoSuchElementException e) {
            System.out.println("空的,空的,一滴都没了");

            for (int i = 0; i < element.length - 1; i++) {
                if (element[i].equals(value)) {
                    T[] b = Arrays.copyOf(element, element.length - 1);
                    for (int j = i; j < b.length - 1; j++) {
                        b[j] = b[j + 1];
                    }
                    element = b;
                    size--;
                }
            }
        }
    }

    public void set(int index,T newValue){
        try{
            checkIndex(index);
        }catch (NoSuchElementException e){
            System.out.print("没这个下标去改变值 ");
            System.out.println(e.getMessage());
        }
        element[index] = newValue;
    }

    public T get(int index){
        try{
            checkIndex(index);
        }catch (NoSuchElementException e){
            //System.out.println("没有这个下标去获取值");
            e.printStackTrace();
        }
        return element[index];
    }

    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0;i<size;i++)
            stringBuilder.append(element[i]);
        return stringBuilder.toString();
    }

    public void checkIndex(int index) throws NoSuchElementException {
        if(index > size-1)
            throw new NoSuchElementException();

    }

    public void checkRemove() throws NoSuchElementException {
        if(isEmpty())
            throw new NoSuchElementException();
    }

    public void checkValue(T value) throws NoSuchElementException {
        int sum = 0;
        for(int i = 0;i<this.size;i++)
            if(element[i].equals(value))
                sum++;
        if (sum == size)
            throw new NoSuchElementException();
    }

    public void show(){
        for(int i = 0 ; i< element.length ; i++){
            System.out.print(element[i] +  " ");
        }
        System.out.println();
    }


    }

2.LinkedList:双向循环链表,依然飞飞飞常重要的存储形式,编码要牢记于心!
(1)允许重复元素,是有序的,允许出现空值
(2)实现代码:

public class withHeadLinkedList <E>{
    protected Node <E> head;

    class Node<E>{
        protected E element;
        protected Node<E> next;

        public Node(E data){
            this.element = data;
        }
    }

    public withHeadLinkedList(){
        head = new Node<>((E)new Object());
    }

    //头插法 head之后添加元素
    public void addHead(E data){
        Node <E> n = new Node(data);
        n.next = head.next;
        head.next = n;
    }

    //尾插法
    public void addTail(E data){
        Node <E> n =new Node(data);
        Node taxi = head;

        while(taxi.next != null)
        {
            taxi = taxi.next;
        }

        taxi.next = n ;
    }

    public String toString(){

        Node <E> taxi = head;
        StringBuilder sb = new StringBuilder();
        while( taxi.next!=null ){
            sb.append(taxi.next.element);
            taxi = taxi.next;
        }
        return sb.toString();
    }

    public void delete( E data){
        Node <E> taxi = head;
        if(data == head.element){
            head = head.next;
        }
        while( taxi.next!= null){
            if(taxi.next.element == data){
                taxi.next = taxi.next.next;
            }
            else
                taxi = taxi.next;
        }

    }

    public E findValue(int index){
        Node<E> taxi = head;
        int num = 0;
        while(taxi.next!= null){
            if(num == index)
                return taxi.element;
            taxi = taxi.next;
            num++;
        }
        return null;
    }

    public int getLength(){
        Node<E> taxi = head;
        int size = 0;
        while(taxi.next!=null){
            taxi = taxi.next;
            size++;
        }
        return size;
    }
    }

三、Queue

1.ArrayDeque:基于双端队列实现,需要使用队列使使用它时间最快

(1)add,remove,get失败会抛出异常,而与之对应的offer,poll,peek失败会返回null。
(2)允许重复元素,是有序的,不允许出现空值

2.PriorityQueue:源码基于小根堆实现
(1)允许重复元素,不是有序的,不允许出现空值

三、HashMap

综合了数组和链表的优点,是一个查询,插入删除都容易的数据结构。

(1)步骤:
①通过hash算法,找到与key对应的存储位置
②访问该位置的value,与当前的value的比较,如果相等就返回,不相等找这个位置对应的链表中的值。

(2)常用hash算法:
加法,乘法,除法,取模法,位运算法等等。

(3)哈希冲突的解决:(在另一篇博客里介绍了,这里不重复)

(4)rehash:
1)为什么要rehash?:之所以要rehash是因为扩容后hash中因为用到了table.length,所以hash出的值一定不一样了,所以要重新hash.
2)rehash之后?:rehash之后可能还在原来的下标,也可能在index+原来table.length的坐标里。

四、Set

1.HashSet:按哈希算法存取对象,速度较快。
2.TreeSet :实现了SortedSet接口,可以对对象排序 ~
3.Set的类都不允许重复元素的出现,且元素是无序的,可以出现null值,但只能出现一次。

发布了24 篇原创文章 · 获赞 0 · 访问量 416
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览