之前工作太忙了,对很多基础知识的学习都停止了,一年了,一年的工作让我明白了很多东西现在打算,从新学习java,这开篇就是arrayList list。本文是以java8为基础而写的。
List 接口继承如下
public interface List<E> extends Collection<E>
public interface Collection<E> extends Iterable<E>
#Iterable
这个继承的顶级是Iterable,这个借口的作用就是规定实现了这个借口的所有类都能够有遍历的方法。
他只有一个Iterator iterator(); 方法这里的Iterator借口 java的集合类中常用的方式是用内部类的方式实现了他。
public interface Iterable<T>
{
Iterator<T> iterator();
}
//java8后这个借口又新增加了两个方法
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
//Spliterator(splitable iterator可分割迭代器)接口是Java为了并行遍历数据源中的元素而设计的迭代器,这个可以类比最早Java提供的顺序遍历迭代器Iterator,但一个是顺序遍历,一个是并行遍历
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
Objects.requireNonNull()判断 是否为空 如果为空就报空指针异常
#Collection接口
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
/*
java1.8 添加的删除删除符合条件的
* @since 1.8
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
/**
*
* @since 1.8
*/
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
/**
*
* @since 1.8
*/
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
/**
*
* @since 1.8
*/
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
}
例如
public void Test1(){
ArrayList<String> tests = new ArrayList<String>();
tests.add("Test1");
tests.add("Test2");
tests.add("Test3");
tests.add("Test4");
tests.removeIf(s -> s.equals("Test1"));//删除Test1
System.out.println(StringUtils.join(tests,","));//输出结果Test2,Test3,Test4
}
Stream<String> stream = tests.stream();
// stream.forEach(System.out::println);
List<String> collect = stream.filter(s -> {
System.out.println(s);
return true;
}).map(s->{
if(s.equals("Test2")){
return "THIS is map";
}else{
return s;
}
}).collect(Collectors.toList());
System.out.println(collect);
//输出结果
/**
Test1
Test2
Test3
Test4
[Test1, THIS is map, Test3, Test4]
**/
stream是java8中新添加的一个类,主要是为了方便对集合类做一些操作例如forEach 遍历集合 map修改某一个对应的集合 filter 过滤集合limit 限定集合大小 sorted对集合排序
Stream 就如同一个迭代器(Iterator),单向,不可以重复使用否则抛出
java.lang.IllegalStateException: stream has already been operated upon or closed
这里 不展开描述java8 使用的Stream Spliterator 感觉这部分的内容有点多,如果要描述牵扯的内容太多,不光有lambda表达式还有并发相关的知识,对并发不是很了解。
IntSummaryStatistics summaryStatistics = datas.stream().mapToInt(x -> x).summaryStatistics();
System.out.println(summaryStatistics.getMax());
这里的 可以先使用stream 转换为数字集合 然后使用IntSummaryStatistics进行操作,可以的到平均值等。
parallelStream 是多线程条件下使用的对集合的操作。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
这里是arraylist 新增加元素,显示要判断长度 如果不够 扩容,扩容使用位运算 向左移动一位 增加1.5倍
删除元素
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
数组删除 使用将 后面的数组copy到前面的,然后在将elementData的最后一位变成null。
ArrayList的基础数据结构是数组,内部对数组的操作 主要是使用
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
来做操作。
JDK8 添加了spliterator()等方法 暂时不做描述。