数据结构

在即将开始找工作之前,还是要先把数据结构要复习一遍,在大学里面上的数据结构是c++实现的,但是这1,2年一直都在用java,c++都忘的差不多了,因此学习数据结构也用c++把,顺便也学习下java.util包。

首先看的数据结构是list 列表,这在java里面有两个实现,ArrayList 和 LinkedList ,今天主要看了ArrayList

首先按照书上教的,自己实现了一个ArrayList ,基本上都是书上的逻辑,大概知道ArrayList是怎么实现的

package com.luolei.util.test.collection;

/**
 * Created with IntelliJ IDEA.
 * User: luolei
 * Date: 2015/9/8
 * Time: 23:04
 */
public class MyArrayList<AnyType> implements Iterable<AnyType> {

    private static final int DEFAULT_CAPACITY = 10;

    private int theSize;
    private AnyType[] theItems;

    public MyArrayList() {
        clear();
    }

    public void clear() {
        theSize = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }
    
    public int size() {
        return theSize;
    }

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

    public void trimToSize() {
        ensureCapacity(size());
    }

    public AnyType get(int idx) {
        if (idx < 0 || idx >= theSize)
            throw new ArrayIndexOutOfBoundsException();
        return theItems[idx];
    }

    public AnyType set(int idx, AnyType newVal) {
        if (idx < 0 || idx >= theSize)
            throw new ArrayIndexOutOfBoundsException();
        AnyType old = theItems[idx];
        theItems[idx] = newVal;
        return old;
    }
    
    public void ensureCapacity(int newCapacity) {
        if (newCapacity < theSize)
            return;
        AnyType[] old = theItems;
        theItems = (AnyType[]) new Object[newCapacity];
        for (int i = 0;i < size();i++) {
            theItems[i] = old[i];
        }
    }

    public boolean add(AnyType x) {
        add(size(),x);
        return true;
    }

    public void add(int idx, AnyType x) {
        if (theItems.length == size())
            ensureCapacity(size() * 2 + 1);
        for (int i = theSize; i > idx; i--)
            theItems[i] = theItems[i-1];
        theItems[idx] = x;
        theSize++;
    }

    public AnyType remove(int idx) {
        AnyType removeItem = theItems[idx];
        for (int i = idx; i < size(); i++)
            theItems[i] = theItems[i+1];
        theSize--;
        return removeItem;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size(); i++) {
            sb.append(i).append(":").append(theItems[i].toString()).append(",");
        }
        if (sb.length() > 1)
            sb.deleteCharAt(sb.length() - 1);
        sb.append("]");
        return sb.toString();
    }

    public java.util.Iterator<AnyType> iterator() {
        return new ArrayListIterator();
    }

    private class ArrayListIterator implements  java.util.Iterator<AnyType> {
        private int current = 0;

        public boolean hasNext() {
            return  current < size();
        }

        public AnyType next() {
            if (!hasNext())
                throw new java.util.NoSuchElementException();
            return theItems[current++];
        }

        public void remove() {
            MyArrayList.this.remove(--current);
        }

    }

}

首先来分析下这段代码,没什么难的逻辑,当new 一个对象时会用默认的构造大小 10 来构造一个,在java.util.ArrayList里面也可以指定构造大小

ensureCapacity 这个方法是按照给定的参数,重新构建一个数组,并将原数据复制到新数组上  这个访问级别应该是public 吗?  回去看下书

add 默认是在末尾加元素,也可以指定添加的位置

不得不说的是这个写法

for (int i = theSize; i > idx; i--)
            theItems[i] = theItems[i-1];

简洁明了,这是书上的写法,以后也要按照这个格式来写

还有就是iterator这个方法

返回的是一个实现Iterator接口的内部类,今天了解到了内部类是可以访问外部类的成员变量的,这样写很方便,也注意到了java.util包中也使用了很多的内部类

 

说完自己写的ArrayList 在说下java.util.ArrayList

这个ArrayList里面的继承和实现关系有点复杂,我对其中的一些关系不是很懂

首先 extends AbstactList extends AbstactCollection  implements Collection

              implements List

   implements List 还有其他的接口,可以忽略,主要是这个接口

Collection接口是顶层接口,所有List 和 set 都实现这个接口

这个接口中定义了一些方法 包括添加,批量添加,删除,批量删除 toArray,size,isEmpty,container等方法

其中还有一个default方法,这也是我今天从中学到的一点新东西,removeif(Predicate<? super E> filter)

根据给定的条件删除,Predicate是个函数式接口,下面给出测试使用这个方法的代码

    @org.junit.Test
    public void testArrayList() {
        List<Integer> list = new ArrayList<>(20);
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        for (int i = 0; i < 10; i++) {
            list.add(5);
        }

        System.out.println("the size is : " + list.size());
        list.removeIf((Integer integer) -> integer == 5) ;

//        list.removeIf(new Predicate<Integer>() {
//            @Override
//            public boolean test(Integer integer) {
//                if (integer == 5)
//                    return true;
//                else
//                    return false;
//            }
//        });
        System.out.println("the size is : " + list.size());
    }

由于是函数式接口,可以用lambda表达式,Predicate接口中也有default方法,估计以后可能会用的and 和 or 方法,可以给定组合条件来删除,比如 比5 大,比10小。当然这个条件也可以直接在一个test方法中判断完。

弄不懂的地方在基础关系以及个别方法,可以看到AbstactList 已经实现了List 接口,ArrayList 又实现List接口,AbstactList 中有些方法已经实现了,ArrayList中又重现实现了一遍,这些地方回去再自习看下。

总结下,ArrayList是由数组实现的,当容量不足时,会重新建立一个数组,新数组的长度为远数组的1.5倍

int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);

其他还有很多方法,回去自习看

posted on 2015-09-09 11:16  头机器人  阅读(179)  评论(0编辑  收藏  举报

导航