数据结构
在即将开始找工作之前,还是要先把数据结构要复习一遍,在大学里面上的数据结构是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);
其他还有很多方法,回去自习看