《Java核心技术 卷1》

第四章 对象与类

4.6 对象构造

4.6.8 对象解析与finalize方法

  1. java不支持析构器。
  2. 可以为类添加finalize方法来回收不使用的对象,但是不要依赖于它,因为很难确定这个方法什么时候才会被调用。
  3. 建议某个资源在使用完毕后立即关闭,那么应该人工管理。对象用完后,可以添加一个close方法来完成相应清理操作

4.7 包

4.7.1 类的导入

4.9 文档注释

4.9.5 通用注释

@see  引用
 - @see #getSecurityManager
 - @see SecurityManager#checkPermission 

第八章 泛型

泛型方法

类型变量放在修饰符的后面,返回类型的前面。


    public static <T> T getMiddle(T... a){
        return a[a.length / 2];
    }

类型变量的限定

extends

规定泛型的上限

PairTest2.java




    public class PairTest2 {    
        public static void main(String[] args) {
            LocalDate[] birthdays= {
                    LocalDate.of(1904, 12, 5),
                    LocalDate.of(1904, 12, 7),
                    LocalDate.of(1992, 4, 25),
                };

            Pair<LocalDate> pair =ArrayAlg.minmax(birthdays);
            System.out.println(pair.getFirst());
            System.out.println(pair.getSecond());
        }
    }

    class ArrayAlg {
        public static <T extends Comparable> Pair<T> minmax(T[] a){
            if(a==null||a.length==0) {
                return null;
            }
            T min=a[0];
            T max=a[0];
            for(int i=1;i<a.length;i++) {
                if(min.compareTo(a[i])>0) {
                    min=a[i];
                }
                if(max.compareTo(a[i])<0) {
                    max=a[i];
                }
            }
            return new Pair<>(min,max);
        }
    }

Pair.java

    public class Pair<T> {
        private T first;
        private T second;

        public Pair(){
            first = null;
            second=null;
        }

        public Pair(T first, T second){
            this.first=first;
            this.second=second;
        }

        public T getFirst() {
            return first;
        }

        public void setFirst(T first) {
            this.first = first;
        }

        public T getSecond() {
            return second;
        }

        public void setSecond(T second) {
            this.second = second;
        }    
    }


super

规定泛型的下限

泛型接口和泛型父类的区别

泛型父类的子类为富二代

  1. 保留父类泛型 –> 子类为泛型
  2. 不保留父类泛型 –> 子类按需实现

属性|方法
随声明的位置而定

泛型擦除


    public class PairErased {
        public static void main(String[] args) {
            // 泛型擦除后,没有指定泛型的具体类型
            MyStudent student = new MyStudent<>();
            student.setJavase(100);
            Object object = student.getJavase();
            System.out.println("object: " + object);

            test(student);

            // 擦除后类似于Object,但是不等于Object
            MyStudent<Object> student2 = new MyStudent<Object>();
            //test(student2);  // Error:The method test(MyStudent<Integer>) in the type PairErased is not applicable for the arguments (MyStudent<Object>)
        }

        public static void test(MyStudent<Integer> stu) {

        }
    }

通配符

  1. ? –> 通配符,类型不确定,用于声明变量|形参上
    –> 不能用在创建泛型类、泛型方法、泛型对象上

  2. 泛型没有数组,泛型没有多态

第九章集合

9.2 具体的集合

9.1.2 Collection接口

iterator方法用于返回一个实现了Iterator接口的对象


    public interface Collection<E> extends Iterable<E> {
        boolean add(E e);       
        Iterator<E> iterator();
    }

9.1.3 迭代器

Iterator接口包含4个方法:

9.2.1 链表


        LinkedList<String> list = new LinkedList<>();
        for (int i = 0; i<list.size();i++) {
            String obj = list.get(i);           
        }

上面这段代码的效率极低。不应该使用上面这种容易让人误解的随机访问方法访问链表。
链表不支持随机访问,如果要查看链表的第N个元素,就必须从头开始,越过N-1个元素。

get方法做了微小的优化: 如果索引大于size() / 2, 就从列表尾端开始搜索元素。

下面是get方法的JDK源码


Java集合框架

Collection接口

是一个泛型接口,继承了迭代器接口。

接口中的所有方法。

ArrayList源码剖析

LinkedList源码剖析

LinkedList的底层通过双向链表实现。

    // 内部类Node
    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;
        }
    }

重要方法

add()
add(E e)


    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;// 原来的链表为空的时候,这时候插入的这个元素就是链表的第一个元素
        else
            l.next = newNode;// 原来链表不为空,将新插入的元素放置 在最后面
        size++;
        modCount++;
    }

add(int, E)
add(int index, E e)


    /**
     * Inserts the specified element at the specified position in this list.
     * Shifts the element currently at that position (if any) and any
     * subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);// 给出的索引等于原链表的长度时候,添加的方式就和上面**add(E e)**一样了
        else
            linkBefore(element, node(index));// 根据索引找到要插入的位置
    }


    /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

remove()

remove(Object o)


    /**
     * Removes the first occurrence of the specified element from this list,
     * if it is present.  If this list does not contain the element, it is
     * unchanged.  More formally, removes the element with the lowest index
     * {@code i} such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
     * (if such an element exists).  Returns {@code true} if this list
     * contained the specified element (or equivalently, if this list
     * changed as a result of the call).
     *
     * @param o element to be removed from this list, if present
     * @return {@code true} if this list contained the specified element
     */
    public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * Unlinks non-null node x.
     */
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }

remove(int index)


    /**
     * Removes the element at the specified position in this list.  Shifts any
     * subsequent elements to the left (subtracts one from their indices).
     * Returns the element that was removed from the list.
     *
     * @param index the index of the element to be removed
     * @return the element previously at the specified position
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        checkElementIndex(index);// 检查索引下标合法性
        return unlink(node(index));
    }

get()


    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }


    /**
     * Returns the (non-null) Node at the specified element index.
     */
    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }


    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;
        }
    }

set()


    /**
     * Replaces the element at the specified position in this list with the
     * specified element.
     *
     * @param index index of the element to replace
     * @param element element to be stored at the specified position
     * @return the element previously at the specified position
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }

ArrayDeque学习

addFirst()


    // The main insertion and extraction methods are addFirst,
    // addLast, pollFirst, pollLast. The other methods are defined in
    // terms of these.

    /**
     * Inserts the specified element at the front of this deque.
     *
     * @param e the element to add
     * @throws NullPointerException if the specified element is null
     */
    public void addFirst(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[head = (head - 1) & (elements.length - 1)] = e;
        if (head == tail)
            doubleCapacity();
    }


    /**
     * Doubles the capacity of this deque.  Call only when full, i.e.,
     * when head and tail have wrapped around to become equal.
     */
    private void doubleCapacity() {
        assert head == tail;
        int p = head;
        int n = elements.length;
        int r = n - p; // number of elements to the right of p
        int newCapacity = n << 1;
        if (newCapacity < 0)
            throw new IllegalStateException("Sorry, deque too big");
        Object[] a = new Object[newCapacity];
        System.arraycopy(elements, p, a, 0, r);
        System.arraycopy(elements, 0, a, r, p);
        elements = a;
        head = 0;
        tail = n;
    }

addLast()


    /**
     * Inserts the specified element at the end of this deque.
     *
     * <p>This method is equivalent to {@link #add}.
     *
     * @param e the element to add
     * @throws NullPointerException if the specified element is null
     */
    public void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            doubleCapacity();
    }

pollFirst()

返回并且删除首端元素


    public E pollFirst() {
        int h = head;
        @SuppressWarnings("unchecked")
        E result = (E) elements[h];
        // Element is null if deque empty
        if (result == null)
            return null;
        elements[h] = null;     // Must null out slot
        head = (h + 1) & (elements.length - 1);
        return result;
    }

pollLast()

返回并删除尾端元素


    public E pollLast() {
        int t = (tail - 1) & (elements.length - 1);
        @SuppressWarnings("unchecked")
        E result = (E) elements[t];
        if (result == null)
            return null;
        elements[t] = null;
        tail = t;
        return result;
    }

peekFirst()

返回但不删除首端元素


    @SuppressWarnings("unchecked")
    public E peekFirst() {
        // elements[head] is null if deque empty
        return (E) elements[head];
    }

peekLast()

返回但不删除尾端元素




    @SuppressWarnings("unchecked")
    public E peekLast() {
        return (E) elements[(tail - 1) & (elements.length - 1)];
    }

猜你喜欢

转载自blog.csdn.net/Jolie_Laide0212/article/details/79383369