当前位置: 首页 > news >正文

中国文化网站建设策划书城阳做网站找哪家好

中国文化网站建设策划书,城阳做网站找哪家好,青岛建设集团有限公司,上海制作网站的公司关于顺序表在前文中就出现了,顺序表的使用这次系统的讲解下 再讲之前先看一下,这篇文章要讲什么: 本篇文章主要讲解的就是这三个。先看第一个: 目录 1.List接口 1.1基础操作 1.2元素操作 1.3批量操作 1.4搜索与定位 1.5视…

关于顺序表在前文中就出现了,顺序表的使用这次系统的讲解下

再讲之前先看一下,这篇文章要讲什么:

本篇文章主要讲解的就是这三个。先看第一个:

目录

1.List接口

1.1基础操作

1.2元素操作

1.3批量操作

1.4搜索与定位

1.5视图与迭代

1.6转换方法

1.7Java 8+ 新增默认方法

1.8Java 9+ 静态工厂方法

1.9继承自 Object 的方法

2.AbstractList抽象类

2.1AbstractList实现List接口的方法

2.2AbstractLis新增的关键方法

2.3AbstractList抽象类的子类责任

3. ArrayList 类

3.1ArrayList 类重写的方法

 3.1.1ArrayList 类的变(常)量

 3.1.2ArrayList 类的新增方法

1.1构造方法

          看完这些下面再手动实现一下,ArrayList 类的基本逻辑

3.1ArrayList 类的实现

3.1.1添加方法

1.1有效元素长度问题

1.2默认容积与动态扩容问题

1.4尾插实现

1.5任意插入

3.1.2删除方法和获取元素、交换元素

1.1删除方法

1.2获取元素

1.3交换元素


1.List接口

List接口 是 Java 集合框架的核心,继承自 Collection 接口,定义了对有序集合的操作。以下是其

所有方法(按功能分类):

1.1基础操作

int size()    返回元素数量
boolean isEmpty()

 判断是否为空

void clear() 清空所有元素

1.2元素操作

boolean add(E e) 尾部添加元素
void add(int index, E element)   指定位置插入元素
E set(int index, E element)替换指定位置元素
E get(int index)  获取指定位置元素
E remove(int index)   删除指定位置元素
boolean remove(Object o)   删除首次出现的指定元素

1.3批量操作

boolean addAll(Collection<? extends E> c)  添加整个集合
boolean addAll(int index, Collection<? extends E> c)从指定位置插入集合(批量插入)
boolean removeAll(Collection<?> c) 删除所有匹配元素
boolean retainAll(Collection<?> c)  仅保留匹配元素
boolean containsAll(Collection<?> c) 判断是否包含整个集合

1.4搜索与定位

int indexOf(Object o) 返回o首次出现位置
int lastIndexOf(Object o) 返回o最后一次出现位置(反向查找)
boolean contains(Object o) 判断是否包含元素

1.5视图与迭代

List<E> subList(int fromIndex, int toIndex)  返回子列表视图
ListIterator<E> listIterator() 返回列表迭代器
ListIterator<E> listIterator(int index) 从指定位置开始的迭代器
Iterator<E> iterator() 返回迭代器(继承自 Collection)

                     迭代即是打印

1.6转换方法

Object[] toArray()转为对象数组
<T> T[] toArray(T[] a)  转为指定类型数组

1.7Java 8+ 新增默认方法

default void replaceAll(UnaryOperator<E> operator)  用操作结果替换所有元素
default void sort(Comparator<? super E> c)   根据比较器排序
default Spliterator<E> spliterator()    返回分割迭代器

1.8Java 9+ 静态工厂方法

static <E> List<E> of()    创建空不可变列表
static <E> List<E> of(E e1)    创建单元素不可变列表
static <E> List<E> of(E... elements)  创建多元素不可变列表
static <E> List<E> copyOf(Collection<? extends E> coll)   创建集合的不可变副本

1.9继承自 Object 的方法

boolean equals(Object o)   比较列表内容是否相等
int hashCode()返回哈希值

这里只需要看下方法搞清 AbstractList 到底实现 List 的哪些方法(以上红色字体的都是被AbstractList 实现的)

2.AbstractList抽象类

AbstractList 是 Java 集合框架中的抽象类,java.util 包中。它提供了List接口的骨架实现,极大简

化了自定义列表的实现过程。

2.1AbstractList实现List接口的方法

boolean addAll(int index, Collection<? extends E> c)批量插入
void clear()清空列表
boolean isEmpty()判断空列表
int size()元素数量
E remove(int index)删除元素
E set(int index, E element)替换元素
E get(int index)获取元素
void add(int index, E element)插入元素
boolean add(E e)添加元素到末尾
Iterator<E> iterator()获取迭代器
ListIterator<E> listIterator()列表迭代器
ListIterator<E> listIterator(int index)从指定位置开始的迭代器
int indexOf(Object o)查找元素位置
int lastIndexOf(Object o)反向查找元素
List<E> subList(int fromIndex, int toIndex)获取子列表

在这里 List 接口基本都在AbstractList 抽象类里面实现,这里只展示了3/2。

这些都是AbstractList抽象类 实现List接口的,下面看 AbstractLis 新增的方法

2.2AbstractLis新增的关键方法

protected void removeRange(int fromIndex, int toIndex)   删除范围元素
protected transient int modCount   修改计数器
public boolean equals(Object o)   列表相等性比较 
public int hashCode()   哈希值计算 

2.3AbstractList抽象类的子类责任

AbstractList的子类必须实现 get() 和 size() ,并根据需要覆盖add(),set(),remove(int) 等方法

(就是get()和 size()是AbstractLis的抽象方法)

可能有人就疑问了:在AbstractList中不是实现了这两个方法了吗?为什么还要实现

1.AbstractList只是提供了List接口的基本实现

2.是因为数据结构的不可知性  看图

可以看到AbstractList的子类有三种且都是类,也就是说至少有三种数据结构,而获取元素(get())和

计算大小(size())的实现完全依赖具体数据结构,所以这是强制的。

前戏准备完毕,下面是本篇文章的重点 ArrayList 类 顺序表的实现

3. ArrayList 类

ArrayList 是 Java 中基于动态数组实现的顺序表,其核心原理是通过维护一个可扩容

的数组来实动态存储,接下来看一下ArrayList 类的关键方法和变(常)量

3.1ArrayList 类重写的方法

AbstractList提供了List接口的基本实现,而ArrayList 继承了AbstractList并重写了父类的关键方法:

public E get(int index)  返回指定位置的元素
public E set(int index, E element) 替换指定位置的元素
public void add(int index, E element)  在指定位置插入元素
public E remove(int index) 删除指定位置的元素
public int size() 返回元素数量
public boolean isEmpty()判断空列表
public void clear() 清空所有元素
public Iterator<E> iterator()  返回迭代器
public ListIterator<E> listIterator() 返回列表迭代器
public int indexOf(Object o)   返回元素首次出现的索引
public int lastIndexOf(Object o) 返回元素最后一次出现的索引
public boolean addAll(int index, Collection<? extends E> c)在指定位置插入集合

 3.1.1ArrayList 类的变(常)量
transient Object[] elementData   存储元素的数组(数据容器)
private int size  当前元素数量(非数组容量 )
private static final int DEFAULT_CAPACITY = 10 默认初始容量(首次添加元素时使用)
private static final Object[] EMPTY_ELEMENTDATA = {}空数组实例(用于空构造)
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} 默认空数组(区分扩容逻辑)

transient 是一个关键字,在后续实现 ArrayList 类 时会将ta改为 private 而 transient 这个后续会说

 3.1.2ArrayList 类的新增方法
public void trimToSize()  将数组容量缩减到当前元素数量
public void ensureCapacity(int minCapacity)预扩容(避免频繁扩容)
private void grow(int minCapacity)内部扩容机制(通常扩容至原容量的1.5倍)
public Object clone() 返回浅拷贝副本
public <T> T[] toArray(T[] a) 返回包含所有元素的数组(类型安全)
protected void removeRange(int fromIndex, int toIndex)移除指定索引范围内的元素
1.1构造方法
public ArrayList()    创建初始容量为10的空列表
public ArrayList(int initialCapacity)  指定初始容量
public ArrayList(Collection<? extends E> c) 用指定集合初始化    
          看完这些下面再手动实现一下,ArrayList 类的基本逻辑

3.1ArrayList 类的实现

ArrayList 是 Java 中基于动态数组实现的顺序表,其核心原理是通过维护一个可扩容

的数组来实动态存储

下面我创建一个 Array类 ,实现一下 ArrayList 类 的核心方法更进一步的了解顺序表:

public Class Array<E>{private E[] es; // 存储元素的数组 }
3.1.1添加方法

在写这个方法前先想问题:

1.添加方法是从头部添加还是尾部添加?

2.是否可以在任意位置添加?

3.如果顺序表满了或顺序表没空间怎么办?

先从第一个问题解决 添加方法是从头部添加还是尾部添加?

这是可能就有人说了:既然考虑到了,添加方法是从头部添加还是从尾部添加 那么不妨创建两个方

法。

但正确答案其实是尾部添加,这是因为头插法的效率太低,每次调用都需要移动所有元素而尾插只需要尾值就行了。

如果使用尾插法,就要解决:有效元素长度问题、扩容与默认容积问题及尾插如何实现:

1.1有效元素长度问题
//有效元素长度问题
public int size(){int count = 0;//计数器for(int i = 0; i < es.length;i++){//判断数组元素是否为空,为空返,不为空++if(es[i] != null){count++;}else if(es[i] == null){return count;}}//极限长度返回if(count == es.length){return count;}return -1;}
如果数组没有空间 返回-1,如果有返回count。
1.2默认容积与动态扩容问题
//默认容积问题
private final int MAXIMUM_LENGTH = 10;//常量public Array() {//构造方法//由于泛型无法实例化(泛型类型不明确),所以将Object强转成泛型数组this.es = (E[]) new Object[MAXIMUM_LENGTH];}//扩容问题public void grow() {//(E[])与上面代码同理E[] container = (E[])new Object[es.length];//接收旧数组元素for(int i = 0; i<size(); i++){container[i] = es[i];}//创建比之前大两倍的数组(这样做之前的元素会消失)es = (E[])new Object[es.length*2];//拿回旧数组的元素for(int i = 0; i<container.length; i++){es[i] = container[i];}}

解决默认容积与扩容问题这两个问题后,连带这个问题也被解决了:如果顺序表满了或顺序表没空间怎么办?

1.4尾插实现
 //尾插实现
public boolean add(E a){//判断有效元素长度是否等于极限值if(size() != es.length) {//不等于时尾插元素es[size()] = a;return true;} else if (size() == es.length) {//等于时扩容grow();//扩容后尾插元素es[size()] = a;return true;}return false;}

现在解决了添加问题和扩容与默认容积问题,就剩下是否可以在任意位置插入 答案是可以的

1.5任意插入

先说一下解决此方法的思路,方法形式为 add(下标,值):

//第一阶段:大纲整理
假设下标为 i = 0,值为 k = 8,数组es内容为{1,2,3,4};也就是将k的值,放在0下标这就意味着数组所有元素都要往后移一位同时之前放在0下标的旧元素也要被保存起来现在整理一下 设i为指向下表的指针,k为指向新值的指针,j为指向旧值的指针

理清了大纲后就要考虑如何实现了

下标:i = 0;
j 做为存储旧元素,首先要做的是保存一份旧元素的副本,为元素交换做准备 即:j = es[i];j 拿到旧元素后,k 值就可以进行新老元素的交换 即:es[i] = k;现在数组情况:es{ 8 , 2 , 3 , 4 , null}下标 0   1   2   3    4
现在 0 坐标的值是:8,下一步就是将 j值 放到 1下标,这意味这指向下标的i要++ 但新的问题出现了
1下标的值也要被保存,所以 j值 不能立即放在1下标,这时可用 k 来存放 1下标的值到这里j k都成为了指向
值的指针(也可以用k来保存j值,j来保存 1下标的值)
即:
i++; i = 1;
k = es[i];
es[i] = j;交换完后继续 i++
i++; i = 2;然后循环就行了
这招我称之为“左右脚交替”(j k不停接收旧值)

最后稍加改造,下面看完整代码:

public void add(int i, E k){E j;//解决尾插问题if(i == size()-1){add(k);return;}//保证es的容量,不等于有效元素的最大值if(size() != es.length|| i != es.length){//循环处理交换while(true){j = es[i];es[i] = k;i++;//奇数段判断if(size() % 2 != 0 && es[i] == null){es[i] = j;return;}k = es[i];es[i] = j;i++;//偶数段判断if(size() % 2 == 0 && es[i] == null){es[i] = k;return;}}//判断数组容量是否大于或等于有效元素最大值} else if (es.length >= size()) {//扩容方法grow();System.out.println("以扩容,请再次调用此方法");}}

现在解释一下,偶数段和奇数段:

ta俩在段中是起到结束循环的作用下面看图:
 

由于 j k 两值是交替保存值的,这就会发生有效元素长度为奇数时正好轮到 j 来保存最后一个值,偶数时 k 轮为保存最后一个值。

看执行结果:

 public static void main(String[] args) {Array<Integer> array = new Array<>();array.add(1);array.add(2);array.add(3);array.add(4);array.add(0,8);array.add(1,9);//打印数组元素方法array.iterate();}结果:8 9 1 2 3 4 
3.1.2删除方法和获取元素、交换元素
1.1删除方法

比较简单 :

  es{ 1 , 2 , 3 , 4}
下标  0   1   2   3 
假设要删除0下标的值:循环{
es[i] = es[i+1];
i++
}
es[size() - 1] = null1 2 3 4 -> 2 2 3 4 -> 2 3 3 4 -> 2 3 4 4 -> 2 3 4直接将想要删除的值覆盖掉,后面一个一个覆盖上,最后将尾值赋为null
public E remove(int index){//判断容量,防止数组越界if(size() != es.length) {int k = index;int size = size();E oldalue = es[index];//控制循环次数,假设index为0,数组长度为4//那么交换次数为 4 - 1(size - (k + 1))for (int i = 1; i <= size - (k + 1); i++) {//交换发生地es[index] = es[index + 1];index++;}//处理尾值es[size() - 1] = null;//返回被删除的值return oldalue;} else if (size() == es.length) {grow();System.out.println("已触发扩容,请重新调用");}//删除失败返回nullreturn null;}
1.2获取元素

这个和幼儿园坐一桌

public E get(int index){return es[index];}
1.3交换元素

这个也和幼儿园坐一桌

public E set(int index, E element){E oldalue = element;//直接交换es[index] = element;//返回被交换值return oldalue;}

看结果:
 

public static void main(String[] args) {Array<Integer> array = new Array<>();array.add(1); 1array.add(2); 2array.add(3); 3array.add(4); 4array.add(0,8); 0array.add(1,9); 被删除array.remove(1); 删除1下标的值Integer i = array.get(1); 获取1下标的值array.set(2,10); 替换2下标的值array.iterate(); 打印数组元素的值System.out.println();System.out.println(i);}
结果:
8 1 10 3 4 
1

结束,下一篇的文章是顺序表的OJ题

http://www.dtcms.com/a/509074.html

相关文章:

  • js前端this指向规则
  • 怎样申请免费网站wordpress 360收录
  • 深圳网站制作公司排名网站建设报班
  • 算命网站开发电话汉服网站的建设
  • 前端-Vue3项目创建以及初始化
  • 网站建设用户登录源码科技小发明小制作
  • 网站设计的大公司上海it驻场服务外包
  • C++:STL--》 mapset以及multsetmultmap的使用
  • 织梦网站建设实训心得黄金网站软件入口免费
  • 01-Kubernetes基本操作
  • 山东网络建站推广我想做电商怎么做
  • 商品网站开发需求表优质的响应式网站建设
  • 操作系统面经1——进程管理
  • 中山微网站建设报价重庆网站建设 重庆网站制作
  • 做视频网站需要什么软件有哪些云电脑免费版永久使用
  • 常州城乡建设局网站网站最新程序策划书
  • 环保局网站建设申请网络游戏名字
  • 阿里Qoder 【新手一小时0-1开发前后端系统】附详细过程
  • 网络营销型网站策划中国软件是外包公司吗
  • 网站建设与管理怎么做塘沽网站优化
  • DeepSeek-AI团队开源的DeepSeek-OCR模型
  • 上海建筑网站建设wordpress添加活动
  • 笔试-模拟打印
  • 中堂东莞网站建设网站界面设计中的版式设计有哪些
  • missionplanner飞行模式参数调参释义一览
  • 撰写网站建设策划书范文专业制作结婚证
  • Pangolin安装记录
  • 网站seo排名优化价格附近的广告公司电话
  • 手机上的应用商店seo做多个网站
  • wordpress表单统计插件西安seo排名扣费