java 数组的扩容,缩容,插入元素,查找元素 详解(通俗易懂)

简介: 非常重要的java数组知识,帮助你更好的理解数组。

目录

 

 

前言 :

一个必须明白的事实(重要!) :

数组的扩容 :

       需求 :

       思路 :

       代码演示 :

数组的缩容 :

       需求 :

       思路 :

       代码演示 :

数组元素的插入 :

       需求 :

       思路 :

       代码演示 :

数组元素的查找 :

       需求 :

       思路 :

       代码演示 :


前言 :

       这篇博文将会和大家分享一下在java中如何实现数组的扩容,缩容,数组元素的插入和查找。首先,我们得知道,java中一个数组一旦被定义,它的长度就是固定的了。java也并没有提供可以直接改变数组长度的方法。所以我们并不能直接对数组进行这些操作,但是,我们可以通过去创建一个新数组去取代旧数组的方式来间接实现我们的需求,我们可以在取代的过程中完成我们的“小心思”。

一个必须明白的事实(重要!) :

       关于Scanner类中的方法nextXxx() 和nextLine() 混用的问题 :

       以nextInt方法为栗,nextInt方法会根据空白字符(如回车,换行,空格等)自动切断你输入的内容,而只保留输入流的第一部分并解析成int类型,其余内容会继续传递下去。而nextLine方法则以换行符作为分隔符。我们知道,在Windows系统下输入Enter键,达到的效果是/r/n,即一个回车键,一个换行键。

       所以,如果你同时使用了nextXxx方法和nextLine方法,且不巧地是,nextXxx方法恰好在nextLine之前,那你就要当心了。你的nextXxx后面的nextLine方法,其收到的内容很可能不是空就是乱七八糟的东西。原因就是我上述说的内容,假设你输入了一个int类型后,敲击Enter键,那么/r就是nextInt结束的标志,而/n就会被nextLine方法当作结束标志,所以此时你的nextLine方法什么都还没有收到就自动结束了,这也是新手常犯的错误之一。

       那么如何解决上述问题呢?其实也不是什么难事,你在nextXxx后面多加一条nextLine() 语句,把它吃剩的垃圾消化一下不就🆗了🐎?

       接下来up演示一段代码,我就在nextInt() 方法后面使用nextLine() 方法,给大家看看实际运行的效果如何,以及通过“消化”改善以后,运行效果如何:

packagecsdn;
/*注意nextXxx() 和 nextLine() 混用时的情况。空白字符: Tab,空格,回车符。*/importjava.util.Scanner;
publicclassTest {
publicstaticvoidmain(String[] args) {
Scannersc=newScanner(System.in);
System.out.println("请尝试输入一个int类型:");
inta=sc.nextInt();
System.out.println("The value of a is : "+a);
Strings=sc.nextLine();
System.out.println("The content of s is : "+s);
if (s.isBlank()) {
System.out.println("这™怎么接收为空啊");
        }
if (s.isEmpty()) {
System.out.println("这™怎么接收为空啊");
        }
if (s.length() ==0) {
System.out.println("这™怎么接收为空啊");
        }
sc.close();
    }
}

image.gif

       我们先仅输入int类型值,看看运行效果如何 :

image.png

       通过运行可以看到,我们输入int类型的一个值后敲回车,还没输字符串啥的呢结果就自动给你蹦出来了,且字符串长度为0的判断为真。

       下面我们试试用空格作为间隔,即输入整型值后,空格,输入其他内容,最后再回车。运行效果如下图所示 :

image.png

       这次我们可以看到,第一次空格前我们输入的22,成功赋值给了整型变量a,而第一次空格后的输入内容,全都向后传递,真好被nextLine接收,赋值给了字符串变量s。可见我们的猜想是正确的。

数组的扩容 :

       需求 :

       给定一个随机类型的数组,以int类型为栗,实现数组的扩容,要求新增加的元素默认放在数组的末尾。而且要求可以任意次给数组扩容,并可以随时停止。        

       思路 :

       1.首先,我们需要创建一个数组,充当已有的数组。接着,用一个变量来接收我们想要添加进数组中的元素。

      2.创建一个新数组,新数组的长度一定是比旧数组长度多1,以存放我们要添加的元素。利用for循环将旧数组的元素一一赋值给新数组,再将添加的元素赋值给新数组。最后只需要改变旧数组的指向,让它指向新数组即可。

       3.想要实现任意次扩容,随时停止,我们想到利用do-while循环,并添加if语句进行判断,触发机制可以自行设置,此处up以字符串是否相当为栗。

       代码演示 :

packagecsdn.array.chinese;
importjava.util.Scanner;
publicclassArrayAddition {
publicstaticvoidmain(String[] args) {
int[] array= {5, 11, 23, 211, 985, 141};
System.out.println("======原先数组的内容为:======");
for (inti=0; i<array.length; ++i) {
System.out.print(array[i] +"\t");
        }
System.out.println();
do {
System.out.println("请输入你想添加到数组中的元素 : ");
Scannersc=newScanner(System.in);
intwantNum=sc.nextInt();
sc.nextLine();
//不要忘记第19行代码"sc.nextLine();" 的作用。int[] arrNew=newint[array.length+1];
for (inti=0, j=0; i<array.length; ++i, ++j) {
arrNew[j] =array[i];
            }
arrNew[array.length] =wantNum;
array=arrNew;
//关键步骤 : 改变原数组的指向。System.out.println("======扩容后数组的内容为:======");
for (inti=0; i<array.length; ++i) {
System.out.print(array[i] +"\t");
            }
/*//System.out.print(arr[i] + "\t"); 注意这行代码 :如果此时制表符用单引号,就会被换算成AscII表值进行计算。所以此处的输出语句中必须使用双引号。加号+是关键,要记住加号+的两种用法。*/System.out.println("\n还想添加吗?输入Yes确定继续,否则程序即会终止。");
Stringtrigger=sc.nextLine();
if ("Yes".equals(trigger)) {
continue;
            } else {
sc.close();
break;
            }
        } while (true);
    }
}

image.gif

       运行效果如下GIF图 :

image.png

数组的缩容 :

       需求 :

       以int型数组为栗,要求默认将数组最后一个元素减去,且在数组长度大于1的情况下,可以任意次对数组进行缩容,当数组长度等于1时,不可再缩容,且需要给出提示。

       思路 :

       1.同数组扩容类似,首先创建一个数组。但不同的是,数组的缩容不再需要定义变量来作接收。

      2.创建一个新数组,长度比旧数组少1,通过for循环将旧数组除去最后一个元素之外的元素一一赋值给新数组,最后改变旧数组的指向。

      3.仍然采用do-while循环来实现多次缩容。

       代码演示 :

packagecsdn.array.chinese;
importjava.util.Scanner;
publicclassArraySubtraction {
publicstaticvoidmain (String[] args) {
int[] arr= {1, 2, 3, 4, 6, 7, 8, 131, 4635, 998};
System.out.println("======初始数组为:======");
for (inti=0; i<arr.length; ++i) {
System.out.print(arr[i] +"\t");
        }
System.out.println();
System.out.println("现在开始对数组进行扩容,进行第一次扩容后 :\n");
do {
Scannersc=newScanner(System.in);
int[] arrNew=newint[arr.length-1];
for (inti=0,j=0; i<arr.length-1; ++i,++j) {
arrNew[j] =arr[i];
            }
arr=arrNew;   //关键 : 改变旧数组的指向。System.out.println("======缩容后的数组为 :======");
for (inti=0; i<arr.length; ++i) {
System.out.print(arr[i] +"\t");
            }
System.out.println("\n如果还想继续缩容,请输入\"Yes\", 否则程序即会终止:");
Stringtrigger=sc.nextLine();
if ("Yes".equals(trigger)) {
continue;
            } else {
sc.close();
break;
            }
        } while (arr.length>1);
if (arr.length==1) {
System.out.println("你知道的,数组的长度必须大于0,所以,没有元素可以减了。");
        } else {
System.out.println("拜拜拉~");
        }
    }
}

image.gif

       运行效果如下:

image.png

数组元素的插入 :

       需求 :

       设法准备一个升序的数组,输入一个你想插入到数组中的值。你需要确定该元素要插到数组中的哪个位置,以保证插入新元素后的数组仍是升序的数组。

       思路 :

      1.要获取一个升序的数组,有多种思路,比如先获取一个任意排列的数组,然后采用冒泡排序法进行升序排列;也可以在for循环中增加判断,以保证你输入的值总比上一个元素的值大。当然,我们需要首先对数组的第一个元素进行单独地赋值,否则你在for循环进行比较时,第一个元素的值是一个垃圾值。

       2.数组的初始长度也可以通过Scanner类的方法手动设置。接着,怎么才能知道新元素要插在哪里呢,这里我们可以采用for循环来遍历数组,但在遍历的过程中进行比较,若发现了大于等于新元素的元素,就把它的索引返回,将来可以把新元素插在该索引处。即将新元素插在大于等于它的元素的前面。

       3.创建一个新数组,利用for循环来进行元素的替换。因为元素的插入是在数组中间完成的,因此,单一循环控制变量无法满足我们的需求,在for循环中我们使用两个变量,其中,j变量表示旧数组的索引,i变量表示新数组的索引。当i变量恰好等于我们之前找到的索引时,将新元素添加到新数组中,而此次循环不再对j变量自增,这样我们就可以实现j变量比i变量少循换一次,以使得后续的替换顺利完成。

       光说多少还是有点抽象,up给大家画一张图就全明白了:如下图

image.png

       其实就是在插入元素时将j跳过了一次。j比i要少自增一次。

       代码演示 :

packagecsdn.array.chinese;
importjava.util.Scanner;
publicclassArrayInsertion {
publicstaticvoidmain(String[] args) {
Scannersc=newScanner(System.in);
System.out.println("请输入初始数组的长度:");
intlen=sc.nextInt();
int[] array=newint[len];
System.out.println("请以升序的方式给数组初始化:");
array[0] =sc.nextInt();
for (inti=1; i<array.length; ++i) {
if ((array[i] =sc.nextInt()) >=array[i-1]) {
continue;
            } else {
System.out.println("错误! 请以升序输入:(你tm不会比大小?)");
i--;
continue;
            }
        }
System.out.println("==============插入新元素前的数组如下:==============");
for (inti=0; i<array.length; ++i) {
System.out.print(array[i] +" ");
        }
System.out.println();
System.out.println("输入你想插入的元素:");
intaddition=sc.nextInt();
intindex=-1;
for (inti=0; i<array.length; ++i) {
if (addition<=array[i]) {
index=i;
break;
            }
        }
if (index==-1) {
index=array.length;   //若数组中没有比新元素大的元素,插在数组的最后就可以        }
int[] arrayNew=newint[array.length+1];
//注意这个for循环,它实现了j比i少循环一次!for (inti=0,j=0; i<arrayNew.length; ++i) {
if (index==i) {
arrayNew[i] =addition;
continue;
            } else {
arrayNew[i] =array[j];
j++;
            }
        }
array=arrayNew;//改变原先数组的指向System.out.println("==============插入新元素后的数组如下:==============");
for (inti=0; i<array.length; ++i) {
System.out.print(array[i] +" ");
        }
sc.close();
    }
}

image.gif

       运行效果 :

image.png

数组元素的查找 :

       需求 :

       创建一个数组,输入要查找的内容,若数组中存在该内容,返回它在数组处的索引值,否则提示找不到该元素。

       思路 :

       1.以字符串数组为栗,创建一个字符串数组。

       2.利用for循环,在遍历数组的同时,用equals() 方法进行元素的判断.

       3.根据判断结果给出用户相应的提示。

       代码演示 :

packagecsdn.array.chinese;
importjava.util.Scanner;
publicclassSearching {
publicstaticvoidmain (String[] args) {
Scannersc=newScanner(System.in);
String[] nameBase= {"King", "Lrving", "Cyan", "Five", "Ice"};
System.out.println("我们先来遍历一下数组:");
for (Strings : nameBase) {
System.out.println(s);
        }
System.out.println("请输入你要查找的元素:");
Stringname=sc.nextLine();
intindex=-1;
for (inti=0; i<nameBase.length; ++i) {
if (name.equals(nameBase[i])) {
System.out.println("恭喜你找到了");
System.out.println("它在数组中索引为:"+i);
index=i;
break;
            }
        }
if (index==-1) {
System.out.println("找不到这个元素呀!");
        }
sc.close();
    }
}

image.gif

       运行效果 :

image.png

System.out.println("END----------------------------------------------------------------------------------");

目录
相关文章
|
26天前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
35 3
|
26天前
|
Java
在Java的世界里,Set只接纳独一无二的元素。
【10月更文挑战第16天】在Java的世界里,Set只接纳独一无二的元素。本文通过拟人化的手法,讲述了重复元素从初次尝试加入Set被拒绝,到经历挣扎、反思,最终通过改变自己,成为独特个体并被Set接纳的全过程。示例代码展示了这一过程的技术实现。
24 1
|
10天前
|
Java 索引 容器
Java ArrayList扩容的原理
Java 的 `ArrayList` 是基于数组实现的动态集合。初始时,`ArrayList` 底层创建一个空数组 `elementData`,并设置 `size` 为 0。当首次添加元素时,会调用 `grow` 方法将数组扩容至默认容量 10。之后每次添加元素时,如果当前数组已满,则会再次调用 `grow` 方法进行扩容。扩容规则为:首次扩容至 10,后续扩容至原数组长度的 1.5 倍或根据实际需求扩容。例如,当需要一次性添加 100 个元素时,会直接扩容至 110 而不是 15。
Java ArrayList扩容的原理
|
4天前
|
Java
那些与Java Set擦肩而过的重复元素,都经历了什么?
在Java的世界里,Set如同一位浪漫而坚定的恋人,只对独一无二的元素情有独钟。重复元素虽屡遭拒绝,但通过反思和成长,最终变得独特,赢得了Set的认可。示例代码展示了这一过程,揭示了成长与独特性的浪漫故事。
13 4
|
11天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
9天前
|
存储 算法 Java
为什么Java Set如此“挑剔”,连重复元素都容不下?
在Java的集合框架中,Set是一个独特的接口,它严格要求元素不重复,适用于需要唯一性约束的场景。Set通过内部数据结构(如哈希表或红黑树)和算法(如哈希值和equals()方法)实现这一特性,自动过滤重复元素,简化处理逻辑。示例代码展示了Set如何自动忽略重复元素。
18 1
|
23天前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
31 4
|
23天前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
19 2
|
26天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
26 4
|
28天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。它通过 hashCode() 和 equals() 方法确保元素唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 实现这一特性。
25 5