文章目录
1.集合(即数据结构)概述
首先我们要知道,Java合集框架中定义的所有接口和类都在java.util包中。
其次我们需要知道Java提供了那些数据结构供我们使用?
Java中的算法结构可分为下面几大种类:
- Set 用于存储一组不重复的元素。(它的重要特性是不重复)
- List 链表(它的重要特性是顺序存储)
- Stack 栈(它的重要特性是:先进后出,后进先出)
- Queue 队列(它的重要特性是:先进先出,后进后出)
- Priority Queue 优先队列(特性的重要特性是优先级)
- Map 映射(特性是键值对存储)
集合框架部分结构图
Jdk中这些集合的通用特性在接口中定义,实现实在具体的类中实现的,如下图:
我们可以看到Set,List,Queue都继承了一个共同的接口Collection.
在Java中基本的数据结构类都继承了Collection接口,所有在Collection接口中定义了一个基本数据结构应该有的操作。
1.1.我们先看下Collection接口定义(了解即可)
1.1.1 接口声明定义
public interface Collection< E > extends Iterable< E >
我们可以看到Collection接口的声明还继承了Iterable接口,这个我们下面再来介绍。
1.1.2 接口方法定义
其中removeIf,Collection中给出了默认实现:
/*
在学习此方法之前我们应先了解什么是default关键字:
https://blog.csdn.net/qq_35835624/article/details/80196932
删除此集合中满足给定Predicate的所有元素。
*/
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;
}
看完上面的Colletion的定义,我们大概知道了定义一个具体集合类需要赋予这个集合类的能力有哪些。
1.2.Iterable接口
下面我们看一下Iterable接口的定义
public interface Iterable<T> {
/*
组合Iterator接口,返回类型为T的元素的迭代器。
*/
Iterator<T> iterator();
/*
为Iterable的每个元素执行给定的操作,直到处理完所有元素或者操作抛出异常。
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);//检查要遍历的对象是否为空
for (T t : this) {
action.accept(t);
}
}
/*
在这个Iterable描述的元素上创建一个Spliterator。
*/
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
它的主要作用在于提供快速遍历集合的一个方式,我们可以看到,这个接口组合了Iterator接口。
下面看一下Iterator接口的定义:
public interface Iterator<E> {
/**
* 判断集合是否拥有下一个元素
**/
boolean hasNext();
/**
* 获取下一个元素
**/
E next();
/**
* 删除当前元素
**/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* 遍历元素
**/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
1.3.Collection的子接口
1.3.1 List接口
Collection的子接口除了继承Collection定义的方法外,还能根据自己的特性自己定义出自己的方法。
1.3.2 AbstractList实现List接口
AbstractList抽象类提供了List接口的部分实现,它的作用是代码复用,减少具体的List实现类的开发难度。
通过上面的学习我们知道了Java中合集数据结构大概的实现流程,我们可以带着这个思路去学习其他的java合集。
1.4 Java定义一个具体集合的步骤
- 根据定义的集合特性新建一个接口并继承Collection接口
- 新建一个AbstractionCollection抽象类实现定义的接口提供一个基础实现
- 最后根据自己的需要继承AbstractionCollection抽象类得到最后的集合实现类
1.5 Java自己动手做一个集合类
通过上面的学习,下面我们来实现一个自己的集合SelfList
1.5.1 定义接口SelfList
package Progress.exa27_1;
import java.util.Collection;
/**
* SelfList接口定义
* @param <E>
*/
public interface SelfList<E> extends Collection<E> {
/**
* 将元素添加到链表头部
* @param e 元素
*/
void addHead(E e);
/**
* 将元素添加到链表尾部
* @param e
*/
void addTail(E e);
/**
* 此方法删除元素
* @param e 元素
* @return
*/
E delete(E e);
E get(int i);
E getHead();
E getTail();
}
1.5.2 定义抽象实现类AbstractionSelfList
package Progress.exa27_1;
public abstract class AbstractionSelfList<E> implements SelfList<E>{
public boolean add(E e) {
throw new UnsupportedOperationException();
}
}
1.5.2 定义具体实现类ArraySelfList
下面展示部分实现部分,完整代码需要访问代码地址去看
package Progress.exa27_1;
import java.util.Collection;
import java.util.Iterator;
/**
* 具体实现
* @param <E>
*/
public class ArraySelfList<E> extends AbstractionSelfList<E>{
int size = 0;
Object[] elementData;
public String toString(){
StringBuilder builder = new StringBuilder();
builder.append("[");
for(Object e:elementData){
if(e!=null){
builder.append(e.toString()).append(",");
}
}
builder.replace(builder.length()-1,builder.length(),"");
builder.append("]");
return builder.toString();
}
public ArraySelfList(){
elementData = new Object[16];
}
public ArraySelfList(int capacity){
elementData = new Object[capacity];
}
@Override
public void addHead(E e) {
//如果是第一次添加
if(size==0){
elementData[0] = e;
} else if(size<elementData.length){
Object[] temp = new Object[elementData.length];
System.arraycopy(elementData,0,temp,1,size);
temp[0] = e;
elementData = temp;
}else{
Object[] temp = new Object[elementData.length+5];
System.arraycopy(elementData,0,temp,1,size);
temp[0] = e;
elementData = temp;
}
size++;
}
@Override
public void addTail(E e) {
if(size<elementData.length){
elementData[size++] = e;
}else{
Object[] temp = new Object[elementData.length+5];
System.arraycopy(elementData,0,temp,0,size);
temp[size++] = e;
elementData = temp;
}
}
@Override
public E delete(E e) {
return null;
}
@Override
public E get(int i) {
if(i<size)
return (E)elementData[i];
else
throw new ArrayIndexOutOfBoundsException();
}
}
1.5.4 测试使用
package Progress.exa27_1;
public class ArraySelfListTest {
public static void main(String[] args) {
ArraySelfList<String> list = new ArraySelfList<>(5);
list.addHead("first");
System.out.println(list);
list.addHead("second");
System.out.println(list);
list.addTail("three");
System.out.println(list);
System.out.println(list.get(2));
}
}
测试结果:
代码地址:
Java基础学习/src/main/java/Progress/exa27_1 · 严家豆/Study - 码云 - 开源中国 (gitee.com)