千家信息网

JAVA中int类型数组怎么修改为泛型

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要介绍"JAVA中int类型数组怎么修改为泛型",在日常操作中,相信很多人在JAVA中int类型数组怎么修改为泛型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
千家信息网最后更新 2025年02月01日JAVA中int类型数组怎么修改为泛型

这篇文章主要介绍"JAVA中int类型数组怎么修改为泛型",在日常操作中,相信很多人在JAVA中int类型数组怎么修改为泛型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JAVA中int类型数组怎么修改为泛型"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

int类型数组

先来一个简单的内容,这个是正常的,以为我在日常的开发中有的时候还是能遇见的,哈哈哈哈,正不正常就以我是不是用过作为标准

public class Main {

public static void main(String[] args) {
Array score=new Array(10);
for(int i=0;i<8;i++){
score.addLast(i);
}

score.add(1,100);
score.addLast(99);
System.out.println(score.toString());

System.out.println(score.find(1));
System.out.println(score.contains(1));
System.out.println(score.remove(1));
System.out.println(score.toString());
System.out.println(score.removeElement(2));
System.out.println(score.toString());
}
}

修改为泛型

public class Array {
private T[] data;
private int size;

public Array() {
this(10);
}

public Array(int capacity) {
//java本身不支持直接new 一个泛型数组,所以用以下方法实现
data = (T[])new Object[capacity];
size = 0;
}

public int getSize() {
return size;
}

public int getCapacity() {
return data.length;
}

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

/**
* 向数组末尾添加元素
*
* @param e
*/
public void addLast(T e) {
add(size, e);
}

/**
* 向数组开头添加元素
*
* @param e
*/
public void addFirst(T e) {
add(0, e);
}

/**
* 向任意合法位置添加元素
*
* @param index
* @param e
*/
public void add(int index, T e) {
if (size == data.length) {
throw new IllegalArgumentException("Add is fail.Array is full");
}

if (index < 0 || index > size) {
throw new IllegalArgumentException("Add is fail.Require index >= 0 and index < size");
}

for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = e;
size++;
}

/**
* 获取索引位置的元素
* 通过这种封装,用户无法查询未使用的空间,保证了数据的安全性。
*
* @param index
* @return
*/
public T get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Get is failed.Index is illegal");
}
return data[index];
}

/**
* 修改索引位置的元素
*
* @param index
* @param e
*/
public void set(int index, T e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Set is failed.Index is illegal");
}
data[index] = e;
}

/**
* 数组中是否包含某个元素
*
* @param e
* @return
*/
public boolean contains(T e) {
for (int i = 0; i < size; i++) {
//注意值的比较应修改为equals方法
if (data[i].equals(e)) {
return true;
}
}
return false;
}

/**
* 查询数组中某个元素的索引
*
* @param e
* @return 没有该元素则返回-1
*/
public int find(T e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}

/**
* 删除index位置的元素,并且返回该元素
* 不用担心删除后原来size位置的元素,因为用无法访问到它。
* 但是最好再写一句data[size]=null 具体原因需要了解java的垃圾回收机制
*
* @param index
* @return
*/
public T remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Remove failed.Require index >=0 and index < size");
}

T ret = data[index];
for (int i = index; i < size - 1; i++) {
data[i] = data[i + 1];
}
//注意维护size
size--;
data[size]=null;
return ret;
}

/**
* 不用担心数组为空的情况,因为数组如果为空,remove方法就会抛出异常
* @return
*/
public T removeFirst(){
return remove(0);
}

public T removeLast(){
return remove(size-1);
}

/**
* 从数组中删除元素e
* @param e
*/
public boolean removeElement(T e){
int index=find(e);
if(index!=-1){
remove(index);
return true;
}else{
return false;
}
}

/**
* 重写toString()方法
*
* @return
*/
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("size= %d,capacity= %d\n", size, data.length));
res.append("[");
for (int i = 0; i < size; i++) {
res.append(data[i]);
if (i != size - 1) {
res.append(",");
}
}
res.append("]");
return res.toString();
}
}

增加数组大小

前面当我们向数组中添加元素时,如果index==size,表示数组已满。

if (size == data.length) {
throw new IllegalArgumentException("Add is fail.Array is full");
}
123

现在可以考虑这样做,依然判断插入位置是否合法,但是当size等于数组长度时,自动为数组扩容--resize(2*data.length);
之所以是扩为原来的2倍,是因为这样扩容量的大小和原来容量大小有关,既不会过小也不会过大。

private void resize(int newCapacity){
T[] newData=(T[])new Object[newCapacity];
for(int i=0;i newData[i]=data[i];
}
data=newData;
}
1234567

减小数组大小

因为有了resize方法,实现起来就很简单了。在remove(int index)方法中,移除一个元素且维护size后,再加上对维护后的size的判断,如下。如果size已经变为capacity的一半,则将数组容量减半。

if(size==data.length/2){
resize(data.length/2);
}
123

注意
resize()方法设为私有,是为了用户只需使用这个数组类,不必去顾虑数组的大小。

时间复杂度的分析

通过对addLast(T[] e)和removeLast(T[] e)时间复杂度的分析,我们发现都是O(n)级别的。但是,这样一般性地考虑最坏的情况在这种情景下是没有太大意义的。因为addLast(T[] e)和removeLast(T[] e)操作并不会经常触发resize(int newCapcity)操作。所以用均摊复杂度分析的话,你会发现这两个操作的均摊复杂度都是O(1)。因此resize(int newCapcity)这样一个比较耗时的操作,如果保证不会每次都会触发,就可以将它的操作耗时分摊到其他操作上。

现在再考虑另外一个场景,就是在addLast(T[] e)操作后,触发了resize(int newCapcity),然后再removeLast(T[] e),又触发了resize(int newCapcity);如此循环。像这样addLast(T[] e)和removeLast(T[] e)的时间复杂度都是O(n)级别的,这就是所谓的复杂度的震荡。以数组这个例子,之所以发生这种情况是因为我们在removeLast操作后,就接着进行了resize操作这样太着急了。那么该如何防止复杂度的震荡呢?
可以这样修改removeLast方法的代码。

if(size==data.length/4 && data.length/4!=0){
resize(data.length/2);
}

加上data.length/4!=0的判断是因为当data.length/4==0的时候,数组长度变为0,这是不合法的。

修改后的完整代码

public class Array {
private T[] data;
private int size;

public Array() {
this(10);
}

public Array(int capacity) {
//java本身不支持直接new 一个泛型数组,所以用以下方法实现
data = (T[])new Object[capacity];
size = 0;
}

public int getSize() {
return size;
}

public int getCapacity() {
return data.length;
}

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

/**
* 向数组末尾添加元素
*
* @param e
*/
public void addLast(T e) {
add(size, e);
}

/**
* 向数组开头添加元素
*
* @param e
*/
public void addFirst(T e) {
add(0, e);
}

/**
* 向任意合法位置添加元素
*
* @param index
* @param e
*/
public void add(int index, T e) {
/*if (size == data.length) {
throw new IllegalArgumentException("Add is fail.Array is full");
}*/

if (index < 0 || index > size) {
throw new IllegalArgumentException("Add is fail.Require index >= 0 and index < size");
}

if(size == data.length){
resize(2*data.length);
}

for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = e;
size++;
}

/**
* 获取索引位置的元素
* 通过这种封装,用户无法查询未使用的空间,保证了数据的安全性。
*
* @param index
* @return
*/
public T get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Get is failed.Index is illegal");
}
return data[index];
}

/**
* 修改索引位置的元素
*
* @param index
* @param e
*/
public void set(int index, T e) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Set is failed.Index is illegal");
}
data[index] = e;
}

/**
* 数组中是否包含某个元素
*
* @param e
* @return
*/
public boolean contains(T e) {
for (int i = 0; i < size; i++) {
//注意值的比较应修改为equals方法
if (data[i].equals(e)) {
return true;
}
}
return false;
}

/**
* 查询数组中某个元素的索引
*
* @param e
* @return 没有该元素则返回-1
*/
public int find(T e) {
for (int i = 0; i < size; i++) {
if (data[i].equals(e)) {
return i;
}
}
return -1;
}

/**
* 删除index位置的元素,并且返回该元素
* 不用担心删除后原来size位置的元素,因为用无法访问到它。
* 但是最好再写一句data[size]=null 具体原因需要了解java的垃圾回收机制
*
* @param index
* @return
*/
public T remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("Remove failed.Require index >=0 and index < size");
}

T ret = data[index];
for (int i = index; i < size - 1; i++) {
data[i] = data[i + 1];
}
//注意维护size
size--;
data[size]=null;

if(size==data.length/4 && data.length/4!=0){
resize(data.length/2);
}
return ret;
}

/**
* 不用担心数组为空的情况,因为数组如果为空,remove方法就会抛出异常
* @return
*/
public T removeFirst(){
return remove(0);
}

public T removeLast(){
return remove(size-1);
}

/**
* 从数组中删除元素e
* @param e
*/
public boolean removeElement(T e){
int index=find(e);
if(index!=-1){
remove(index);
return true;
}else{
return false;
}
}

/**
* 重写toString()方法
*
* @return
*/
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("size= %d,capacity= %d\n", size, data.length));
res.append("[");
for (int i = 0; i < size; i++) {
res.append(data[i]);
if (i != size - 1) {
res.append(",");
}
}
res.append("]");
return res.toString();
}

private void resize(int newCapacity){
T[] newData=(T[])new Object[newCapacity];
for(int i=0;i newData[i]=data[i];
}
data=newData;
}
}

到此,关于"JAVA中int类型数组怎么修改为泛型"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

数组 元素 方法 位置 复杂 复杂度 索引 类型 大小 不用 情况 学习 查询 合法 时间 用户 保证 分析 安全 之所以 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 天津虚拟主机租用云空间云服务器 基岩版服务器怎么样 服务器在海里安全吗 服务器刷物品网易版 美国国家网络安全战略律法 网络安全竞赛优秀作品 阿里巴巴网络技术有限公司市值 计算机网络技术及应用十三五教材 steam方舟应该进哪个服务器 闵行区参考软件开发价格咨询 巨杉数据库集群安装 优倍快网络技术测试面试 普陀区优势软件开发产品介绍 数据库查询学分为5分的课 网络安全维护培训通知 php访问别人的数据库 成都办公系统软件开发有用吗 怎么查服务器的公网地址 mysql数据库层次结构 实现网络安全的防范措施有哪些 宣讲网络安全知识小结 太阳能服务器上市公司 寻找网络技术合作 服务器属于什么行业 小型软件开发省钱 pip换成国内服务器 服务器错误代码但未保存怎么处理 实时数据库 中标 荔湾app软件开发哪家好 做网络运维好还是软件开发好
0