Java---入门基础篇(下)---方法与数组

前言

本篇文章主要讲解有关方法与数组的知识点 ,是基础篇的一部分 , 而在下一篇文章我会讲解类和对象的知识点 

入门基础篇上的链接给大家放在下面啦 !

Java---入门基础篇(上)-CSDN博客

感谢大家点赞👍🏻收藏⭐评论✍🏻

欢迎各位大佬指点,相互学习,一起进步!


目录

前言

一.方法的使用

1.什么是方法?

2.方法的定义

3.方法调用的执行过程

4.实参和形参的关系 

5.没有返回值

二.方法重载

1.什么是重载?

2.方法重载的概念

三.递归

1.什么是递归?

2.执行过程分析

3.练习

四.数组的基本概念

1.数组的创建与定义

2.数组的使用

2.1.数组访问:

2.2.遍历数组:

3.数组是引用类型

3.1基本数据类型与引用数据类型的区别

3.2空引用null

3.3参数传参

3.4返回值

五.数组练习 

1.数组转字符串

2.数组拷贝 

3.查找数组中的指定元素 

4.判断一个数字是否存在于数组中 

5.冒泡排序

 6.数组逆序

六.二维数组 


一.方法的使用

1.什么是方法?

方法就是一个代码片段 , 学会C语言的伙伴们可以发现与  C 语言中的 " 函数 "类似:
比如:有三个人分别来问我相同的问题,我每次都要回答他们一遍 , 很麻烦,但如果我一次把问题整理好每当有人来问的时候我直接把文件发给他 , 就会容易很多 , 不用重复的做一样的工作了.

优点:

  • 一个代码可以在多个位置使用
  • 让代码更好理解更简单 
  • 直接调用现有的开发 , 不用重复做繁琐的工作 

2.方法的定义

修饰符 返回值类型 方法名称(参数类型 形参 ...){
方法体;
return 返回值;
}

eg:判断是否为闰年 

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("请输入年份:  ");
            int year = sc.nextInt();
            boolean a = isLeapYear(year);//调用方法时也要定义变量,并写上类型
            System.out.println(year + "是闰年吗? 请回答:" + a);
        }
    }


    public static boolean isLeapYear(int year) {//此为方法的部分 
        if (year % 100 == 0) {
            if (year % 400 == 0) {
                return true;
            } else {
                return false;
            }
        } else {
            if (year % 4 == 0) {
                return true;
            } else {
                return false;
            }
        }
    }
}

 

上面所展示的是一个参数的写法 , 下面介绍两个参数是如何编写

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入:");
        int sum1 = sc.nextInt();
        int sum2 = sc.nextInt();
        int d = add(sum1, sum2);//实际参数,需要两个
        System.out.println(d);
    }

    public static int add(int x, int y) {//形式参数,需要两个
        return x + y;
    }
}
注意:
1. 修饰符:现阶段先直接使用 public static 固定搭配,下一篇文章会讲解类的使用
2. 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果 没有返回值,必须写成 void
无返回值:  下面会讲(5.)
3. 方法名字:采用 小驼峰 命名(属于软性规则) eg: isLeapYear (只有第一个单词首字母小写)
4. 参数列表:如果方法没有参数, ()中什么都不写 ,如果有参数,需指定参数类型,多个参数之间使用逗号","隔开
5. 方法必须写在类中 ,就像上述代码一样,都写到了public class Test中
6. 方法不能嵌套定义 ,但是可以嵌套调用

3.方法调用的执行过程

调用方法 --- > 传递参数 --- > 找到方法地址 --- > 执行被调方法的方法体 --- > 被调方法结束返回 --- > 回到主调方法继续往下 执行

方法中结束的标志时遇到return,没有返回值就是执行到'' } "

下面用一个具体的例子直观的展示方法的优点:

计算1!+2!+3!+4!...+n!

不包含方法的写法:(运用了多次循环嵌套,不是很直观)

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入");
        int n = sc.nextInt();
        int sum = 0;
        int m=1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= 1; j++) {
                m = m * i;
            }
            sum=sum+m;
        }
        System.out.println(sum);
    }

 而运用了方法之后,避免了使用二重循环,让代码更简单清晰

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入");
    int n = sc.nextInt();
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        sum = sum + mul(i);
    }
    System.out.println(sum);
}
public static int mul(int a) {
    int m = 1;
    for (int i = 1; i <= a; i++) {
        m = m * i;
    }
     return m;
}

4.实参和形参的关系 

形参的名字可以随意取,对方法都没有任何影响,形参只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值 。比如:
我们想实现两数交换的函数,但结果并没有成功是为什么呢?
可以看到,在 swap 函数交换之后,形参 x y 的值发生了改变,但是 main 方法中 a b还是交换之前的值,即没有交换成功。因为 Java 中,实参的值永远都是拷贝到形参中,形参和实参本质是两个实体.  详细来说:
  • 实参a和bmain方法中的两个变量,其空间在main方法的栈(一块特殊的内存空间)中,而形参x和yswap方法中的两个变量,xy的空间在swap方法运行时的栈中,因此:实参ab 与 形参xy是两个没有任何关联性的变量.
  • swap方法调用时,只是将实参ab中的值拷贝了一份传递给了形参x和y,因此对形参xy操作不会对实参ab 产生任何影响。即:调用

在c语言中可以用到指针来交换,那么Java中应该怎么办呢?

引用类型参数,在下面的数组会讲解.

5.没有返回值

有返回值时需要接收, 可以用变量来接收,也可以放入打印里 

注意:接收的变量的类型和方法的返回值类型要一致(也可以是能通过隐式转换或者是显式转换过去的)

System.out.println(add(a));

没有返回值时,返回值类型必须写成void 

可以不用接收直接调用 

二.方法重载

1.什么是重载?

首先看下面这张图 , 我们要实现的是两个数字相加的程序 ,由于我们只设置了int类型的两数之和的方法 , 会导致double类型的报错 

所以我们需要再加上double类型的两数之和相加 , 我们发现:虽然都是时间加和的程序 , 但是它们的命名并不相同

并且如果有很多不同的相加程序,所起的名字也会变得更加麻烦 ,比如下面的程序:

都是表示相加的程序 , 但他们可能是个数不一样 , 或者是类型不一样 , 这就导致了我们要起四个不同的名字 , 会变得更加繁琐 , 那么可不可以所有表示相加的都起一样的名字呢 ?

 .答案是可以的 这时,我们就可以使用方法重载

即全部命名为add,这个在Java中是可以实现的 ,但是要注意:相同的方法命名它们 不是类型不同 就是个数不同 ,否则就是重定义了,如下:

下图就表示重定义 , 即使他们变量名字不同,只要红色的地方一样 , 就不叫做方法重载 

返回值类型改成double了也不可以构成重载 , 只看我画红色的地方

2.方法重载的概念

1)在 Java 中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了
(也就相当于"一词多义")
2)注意:
  •  方法名必须相同
  •  参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
  •  与返回值类型是否相同无关
  •  编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法

三.递归

1.什么是递归?

从前有坐山,山上有座庙,庙里有个老和尚给小和尚将故事,讲的就是:
" 从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事,讲的就是:
" 从前有座山,山上有座庙 ..."
" 从前有座山 ……"
"
又或者,梦中梦,一环扣一环
递归也是如此,a方法中又重新调用着a方法.
eg:递归求n 的阶乘
public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入: ");
        int n = scanner.nextInt();
        int ret = fact(n);
        System.out.println(ret);
    }

    public static int fact(int n) {
        if (n == 1) {
            return 1;
        }
        return n * fact(n - 1);
    }
}

2.执行过程分析

在Java中每一次调用,都需要为本次方法调用在内存的栈区申请一块内存空间来保存方法调用期间的各种局部变量的值,这块空间被称为栈帧。

方法不返回,方法对应的栈帧空间就一直占用,所以函数调用中存在递归调用的话,每一次递归调用都会开辟属于自己的栈帧空间,直到递归不再继续,开始回归,才逐层释放栈帧空间。

所以如果采用方法递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出的问题。

3.练习

1)分析:输入一个整数,按照顺序打印一个整数的每一位

eg:

输入:1234 输出:1 2 3 4

1234

1234%10=4

1234/10=123

123%10=3

123/10=12

12%10=2

12/10=1

1%10=1

1/10=0

 以上方法容易理解但是很麻烦,所有数都需要一个一个打,但是数字很大就无法做到了

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入: ");
        int n = scanner.nextInt();
         print1(n);
    }

    public static void print1 (int n) {
        if(n>9){
            print1(n/10);//目的是将位数减一位
        }
        System.out.println(n%10);
    }
}

2).递归求 1 + 2 + 3 + ... + 10 

public class Test {
    public static void main(String[] args) {
        int ret = add(10);
        System.out.println(ret);
    }

    public static int add(int n) {
        if(n==1){
            return 1;
        }
        return n+add(n-1);
    }
}

注意:如果上述的方法去掉n==1就返回的程序,那么会导致程序一直循环进行 , 而递归调用方法的时候会创建栈帧 , 递归几次就会创建几层 , 每层栈帧都会消耗一定的存储空间的 , 达到一定层数后就可能把栈空间给消耗完毕了  

3).写一个递归方法,输入一个非负整数,返回组成它的数字之和 . 例如,输入 1729, 则应该返回 1+7+2+9,它的和是 19
public class Test {
    public static void main(String[] args) {
        int n = 1729;
        int ret = add(n);
        System.out.println(ret);
    }
    public static int add(int n) {
        if (n < 9) {
            return n;
        }
        return n % 10 + add(n / 10);
    }
}

 4)斐波那契数列

public static int fib(int n) {
if (n == 1 || n == 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}

从这里我们也可以看到虽然才算到第6项,但是需已经调用方法很多次了,当执行fib(40)的时候,次数高达1亿多次,进行了太多的重复运算, 而每一次递归调用都会开辟属于自己的栈帧空间,所以当我们求fib(50)时,就会发现半天不出结果,结果还为负数,原因是开辟了太多的栈帧空间,导致溢出了

解决办法(针对斐波那契): 循环

public static int fib(int n) {
int last2 = 1;
int last1 = 1;
int cur = 0;
for (int i = 3; i <= n; i++) {
cur = last1 + last2;
last2 = last1;
last1 = cur;
}
return cur;
}

四.数组的基本概念

1.数组的创建与定义

如果想要打印出5个商品的价格,那么就要设立5个变量,那么要是100个商品呢,难道要设置100的变量吗?有没有一次就能打印出所有价格的方法呢?数组就可以做到

那么什么是数组?

数组就是相同类型的元素集合,且空间连在一起

下面来讲解如何创建数组?

1.数组的创建

T[] 数组名 = new T[N];
//T为数组存放的元素类型
//T[]为数组的类型
//N为数组的长度
//new为关键字

eg:创建一个可以容纳10个int类型元素的数组

int[] array = new int[10];

2.数组的初始化 

1)动态初始化:直接指定数组中的元素个数 

int[] array = new int[10];

2)静态初始化:不指定数组中的元素个数 , 而是根据后方{}里的元素个数 , 来计算数组中的长度

int[] array = new int[]{1,3,4,2,2,2,5,5};

 注意1:静态初始化

  • {}内的元素类型要与[]前的类型一致
  • new int[]可以省略,为int[] array = {1,3,4,2,2,2,5,5};
  • 虽然省略了new int[] , 但是编译器编译代码时还是会还原

注意2:在c语言中,定义数组的方法为  int array[] = {1,3,4,2,2,2,5,5};

虽然java中也可以这样写,但是不建议,因为int[]在一起更能直观的表示为int类型的数组

否则可能理解为数组的类型为int .

注意3:两种初始化格式都可以分为两步

int[] array; 
array=new int[]{1,3,4,2,2,2,5,5};

但如果是静态初始化中的省略格式则不能分为两步,下面所述代码就是一个错误示范. 

int[] array;
array = {1,3,4,2,2,2,5,5};

注意4:如果没有对数组进行初始化,数组中元素有默认值  

 eg:如果数组中的元素为基本数据类型 , 默认值为对应类型对应的默认值

类型默认值
byte 0
shut 0
int0
long0
float0.0f
double0
char/u0000
booleanFALSE
注意:如果数组中存储元素类型为引用数据类型 , 默认值为null 

2.数组的使用

2.1.数组访问:

数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标,数组可以通过下标访问其任意位置的元素。比如:

同时,我们也可以通过赋值改变某项的值

注意1:数组的内存空间是连续的 , 因此支持随机访问

(ps:随机访问:随机访问是指可以直接访问任意存储单元中的数据,而不需要按照顺序逐个读取 , 数组的随机访问意味着可以直接、快速地访问数组中的任何元素,而无需按顺序遍历数组)

注意2:注意不要越界 , 例如上图中array数组中最大的下标为4 , 不能超过4,否则会出现以下提示 

错误提升如下

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
	at Test.main(Test.java:8)
//线程 “main” java.lang 中出现异常。at Test.main(Test.java:8)数组索引越界异常:
索引 5 超出长度 5 的界外

2.2.遍历数组:

1) 第一种方法是分别访问数组中的每一个元素并进行打印 

int[] array = {1,3,5,7,9};
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[5]);

但是如果数组中元素有很多长达几百个时 , 难道需要几百个打印语句吗 ?

2)循环打印数组中的每一个元素 

int[] array = {1,3,5,7,9};
for(int i=0;i<array.length;i++) {//注意:.是成员访问运算符,array.length就是求数组中的元素个数
    System.out.println(array[i]);
}
//打印结果:
1
3
5
7
9

3)使用for-each遍历数组 

int[] array = {1,3,5,7,9};
for(int num:array){
    System.out.println(num);
}
//打印结果
1
3
5
7
9

注意:   for-each方法虽然简单 , 但存在很多限制 , 只能读取数组元素  , 而不能修改 , 只能按照顺序从前往后读取 (只是将数组中的元素保存在了变量中 )

eg: 当我们想要修改数组中的元素时,for-each的改法如下,但事实上并没有改变数组的元素大小,而是改变了num这个变量的大小 .

int[] array = {1,3,5,7,9};
for(int num:array){
    num = num*100;
    System.out.println(num);
}

//此代码相当于for循环中的如下写法
 for(int i=0;i< array.length;i++){
     int num = array[i];
     num= num*100;
     System.out.println(num);
 }

正确方法如下:

int[] array = {1,3,5,7,9};
for(int i=0;i< array.length;i++){
   array[i] = array[i]*100;
    System.out.println(array[i]);
}
//打印结果
100
200
300
400
500

 4)通过数组名来打印数组 

int[] array = {1,3,5,7,9};
System.out.println(Arrays.toString(array));
//打印结果
[1, 3, 5, 7, 9]

3.数组是引用类型

3.1基本数据类型与引用数据类型的区别

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值
引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址

引用数据类型包括:类、 接口、 数组、 枚举、 注解等

主要区别:

基本数据类型是直接保存在栈中的

引用数据类型在栈中保存的是一个地址引用,这个地址指向的是其在堆内存中的实际位置。(栈中保存的是一个地址,而实际的内容是在堆中,通过地址去找它实际存放的位置)

引用数据类型在创建时,系统会分配两块空间,一块存放引用地址,一块存放实际的对象

引用数据类型赋值给另一个变量时,赋的是内存地址,而不是实际的数据

public static void func() {
int a = 10;
int b = 20;
int[] arr1 = new int[]{1,2,3};
int[] arr2 = arr1;//将arr1的地址赋值给arr2
}

如果两个引用数据的变量指向同一个对象时,一个变量修改值,另一个变量的值一样会受到影响。

public static void func() {
int a = 10;
int b = 20;
int[] arr1 = new int[]{1,2,3};
int[] arr2 = arr1;//将arr1的地址赋值给arr2
arr2[0]=100;
}

因为arr1和arr2的地址是一样的 , 那他们对应的堆中对应的内容就是一样的 ( 因为是根据地址来找对应的堆的内容 )

当代码添加arr2[0]=100时,也就相当于修改了堆中的内容 , 所以arr1中的内容也会被修改

举例来说:

如果引用是一把钥匙(arr1是一把钥匙 , 又配了一把一样的钥匙 , 也就是arr2) 

存在于堆中的 new 出来的数组本体,看作是一个房子 , 那么如果通过arr2钥匙修改了房子中的内容那么arr1钥匙打开看到的也是被修改的. 

从上图可以看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。只有以下四种: 

  • 引用像指针一样能保存内存地址 
  • 引用可以相互赋值 或 判断相等
  • 针对数组的引用 , 可以用 [] 访问元素
  • 成员访问功能 

3.2空引用null

null在Java中表示"空引用",即不指向对象的引用 

类似c中的空指针NULL ,都表示无效的内存位置

那么空引用到底有什么用处呢?

空引用主要是用来表示,一个对象还没有被初始化,当你在代码里可能需要先声明一个变量,但是呢,又不想马上给它分配内存空间,这时候就可以用空引用了。还有就是,比如说你要返回一个对象,但是呢在某些情况下又没有合适的对象可以返回,这时候也可以返回一个空引用。不过,空引用确实容易出问题,所以在Java里边,从Java七开始吧,就引入了Optional类,来处理空引用的问题,这样就更安全一些。

3.3参数传参

1)

 public static void main(String[] args) {
        int[] arr1 = new int[]{1,2,3};
        func(arr1);
        System.out.println(arr1[0]);
    }

    public static void func(int[] arr2) {//将arr1的地址复制给arr2
        arr2[0] = 10;//通过地址来找到实际的内容并修改
        System.out.println(arr2[0]);
    }
//打印结果
10
10

注意:传过去的是地址,所以arr2可以根据地址找到实际的值并修改,所以arr1与arr2都被修改

2)

public static void main(String[] args) {
        int[] arr1 = new int[]{1,2,3};
        func(arr1);
        System.out.println("arr1[0]为"+arr1[0]);
    }

    public static void func(int[] arr2) {//将arr1的地址复制给arr2
        arr2 = new int[]{3,4,5};//将此数组的首地址赋值给arr2
        //注意这块不要重定义
        // 上一行代码已经定义过它是一个int类型的数组了
        System.out.println("arr2[0]为"+arr2[0]);//此打印是根据arr2来找到的实际的内容
    }
//打印结果
arr2[0]为3
arr1[0]为1

注意:虽然传过去的也是地址但是在func方法中修改了arr2的地址  

即:1)修改了实际的内容(改了房子里的布置)

    2)修改了地址(换成了另一把钥匙打开了另一座房子)

总结:

  • 方法内部针对引用的修改 , 不总是能影响到外面的 , 关键要看对引用修改是怎样的操作 
  • 如果修改的是引用指向的对象本体(通过 [ ] . ) , 此时的修改是能够被方法外部感知到的 
  • 如果修改的是引用本身(通过=修改引用中保存的地址), 此时的修改不能被方法外部感知到

3.4返回值

(上图画红框处,左边的代码为Java,右边为c语言)

在C语言中定义的a数组是局部变量 , 当执行完函数之后 , 局部变量就释放内存 , 如果在函数外部调用 , 由于数组所在的空间已经被销毁了 , 返回了数组的首地址也根本不会找到它 , 即为访问非法的内存空间 , 因此右侧c语言的写法是错误的 .

(相当于已经把酒店的房间退了 , 但是用私自配的房卡 , 强行开这个门 , 看到的房间里的内容是随机的 )

在Java中数组的实际内容 , 是存在于中的 , 但是随着方法的结束 , 销毁的是a引用 , 并没有消除堆上数组的实际内容 , 所以a引用的地址指向的内存是仍然有效的 . 因此Java的写法是正确

那怎么释放堆上的空间呢?什么时候会被释放掉呢?---"垃圾回收机制 "

答案是:你new出来的对象或数组当你的代码中没有任何地方使用这样的对象或数组的时候就会被JVM自动释放掉 , 完全不需要自己写代码来进行干预 , JVM察觉出来你一定不会用到它时就会释放掉 , 这样的机制称为"垃圾回收机制",简称GC.

  • 缺点:
  • 消耗更多的系统资源来实现自动释放内存功能
  • 运行过程中消耗更多的时间

例如:求斐波那契数列前10项.

public class Test {
    public static void main(String[] args) {
        System.out.println("请打印斐波那契数列的前十项: ");
        int arr[] = func(10);
        System.out.println( Arrays.toString(arr));
    }

    public static int[] func(int n) {
        int[] arr= new int[n];
        if (n <= 0) {
            return null;
        }
        if (n > 0) {
            arr[0] = 1;
            arr[1] = 1;
            for (int i = 2; i < n; i++) {
                arr[i] = arr[i - 1] + arr[i - 2];
            }
        }
        return arr;
    }
}

五.数组练习 

1.数组转字符串

使用Java自带的方法---Arrays.toString(arr)

需要添加---import java.util.Arrays

import java.util.Arrays
int[] arr = {1,2,3,4,5,6};
String newArr = Arrays.toString(arr);
System.out.println(newArr);
// 执行结果
[1, 2, 3, 4, 5, 6]

那么这个自带的方法是如何实现的呢?

在这之前大家需要知道的是字符串是可以通过加号连接在一起的 

 

所以模拟实现此方法的代码为:

public static String ArraytoString(int[] arr) {
    String result = "[";
    for (int i = 0; i < arr.length; i++) {
        result += arr[i];
        if(i<arr.length-1){
            result += ",";
        }
    }
    result += "]";
    return result;
}

2.数组拷贝 

第一种方法: int[] newarr = arr;//复制数组对应的地址

第二种方法: Arrays.copyOf(arr, arr.length);//复制数组的实际内容

import java.util.Arrays;
public static void func(){
// newarr和arr引用的是同一个数组
// 因此newarr修改空间中内容之后,arr也可以看到修改的结果
int[] arr = {1,2,3};
int[] newarr = arr;
newarr[0] = 100;
System.out.println("newarr: " + Arrays.toString(arr));//打印结果为{100,2,3}


// 使用Arrays中copyOf方法完成数组的拷贝:
// copyOf方法在进行数组拷贝时,创建了一个新的数组,只是内容一样,但无关系
// arr和newarr引用的不是同一个数组,是两个内容相同的数组
arr[0] = 100;
newarr = Arrays.copyOf(arr, arr.length);
System.out.println("newarr: " + Arrays.toString(newarr));//打印结果为{1,2,3}
}

 

所以第二种方法在修改其中一个数组内容的时候 ,不会影响另一个,都是独立个体.

注意:也可以拷贝某一部分的范围 

同样我们来实现Arrays.copyOf此方法的编写过程

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int[] arr2=copyOf(arr,7);
    }
    public static int[] copyOf(int[] arr,int newLength) {
        int[] result = new int[newLength];//定义数组长度为7
        int len = Math.min(arr.length,newLength);
        for(int i=0;i<len;i++){
            result[i]=arr[i];//只复制过去了前五项,一开始全部为0
        }
        return result;//最后返回数组的内容
    }
}

3.查找数组中的指定元素 

给定一个数组, 再给定一个元素, 找出该元素在数组中的位置

(顺序查找)

//顺序查找
public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int ret = search(arr,3);
        System.out.println(ret);
    }
    public static int search(int[] arr,int a) {
        for(int i=0;i<arr.length;i++){
            if(a==arr[i]){
                return i;
            }
        }
        return -1;
    }
}
//结果为2

(二分查找) 

public class Test {
    public static void main(String[] args) {
        int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15,16,17,18,19,20};
        System.out.println(binarysearch(arr1, 8));

    }

    public static int binarysearch(int[] arr, int tofind) {
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (tofind < arr[mid]) {
                right = mid - 1;
            } else if (tofind > arr[mid]) {
                left = mid + 1;
            } else {
                return mid;//找到了返回下标
            }
        }

        return -1;//没找到退出
    }
}

4.判断一个数字是否存在于数组中 

public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        Scanner sc = new Scanner(System.in);
        int ret =sc.nextInt();
        System.out.println(search(arr,ret));
    }
    public static boolean search(int[] arr,int a) {
        for(int i=0;i<arr.length;i++){
            if(a==arr[i]){
                return true;
            }
        }
        return false;
    }
}

5.冒泡排序

假设排升序:
1. 将数组中相邻元素从前往后依次进行比较,如果前一个元素比后一个元素大,则交换,一趟下来后最大元素
就在数组的末尾
2. 依次从上上述过程,直到数组中所有的元素都排列好
import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int[] arr1 = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 48, 19, 50};
        bubblesort(arr1);
        System.out.println(Arrays.toString(arr1));
    }

    public static void bubblesort(int[] arr2) {
        for (int i = 0; i < arr2.length - 1; i++) {
            for (int j = 1; j < arr2.length - i;j++) {
                if (arr2[j - 1] > arr2[j]) {
                    int tmp = arr2[j - 1];
                    arr2[j - 1] = arr2[j];
                    arr2[j] = tmp;
                }
            }
        }
    }
}

 6.数组逆序

设定两个下标 , 分别指向第一个元素和最后一个元素 . 交换两个位置的元素 .
然后让前一个下标自增 , 后一个下标自减 , 循环继续即可数
public class Test {
    public static void main(String[] args) {
        int[] arr = {2,1,5,8,6,3};
        reserve(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void reserve(int[] arr) {
        int left=0;
        int right=arr.length-1;
        while(left<right){
        int tmp=arr[left];
        arr[left]=arr[right];
        arr[right]=tmp;
        left++;
        right--;
        }
    }
}

六.二维数组 

二维数组本质上也就是一维数组 , 只不过每个元素又是一个一维数组 .
数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
注意:二维数组的用法和一维数组并没有明显差别
同理 , 还存在 " 三维数组 ", " 四维数组 " 等更复杂的数组 , 只不过出现频率都很低 .
注意:在Java中,数组的长度不要求一致,注意和C语言进行区分
本次内容就到这里啦,大家基础一定要打好,后面的学习也会上升难度了

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980478.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论coding能力 new bing 对比 chatgpt

近日需要编程计算每个月的第二个星期二是哪一天&#xff0c;因为那一天需要做一件重要的事情&#xff0c;我想在这个日期做一个提醒&#xff0c;于是把这个重任交给当下最火的AI&#xff0c;微软new bing和chatGPT&#xff0c;实验对比结果如下&#xff1a;微软new bing会给你参…

C语言:51单片机 基础知识

一、单片机概述 单片机的组成及其特点 单片机是指在一块芯片上集成了CPU、ROM、RAM、定时器/计数器和多种I/O接口电路等&#xff0c;具有一定规模的微型计算机。 特点&#xff1a; 1、单片机的存储器以ROM、RAM严格分工。 2、采用面向控制的指令系统。 3、单片机的I/O口引脚通…

【计算机网络入门】初学计算机网络(六)

目录 1.回忆数据链路层作用 2. 组帧 2.1 四种组帧方法 2.1.1 字符计数法 2.1.2 字节填充法 2.1.3 零比特填充法 2.1.4 违规编码法 3. 差错控制 3.1 检错编码 3.1.1 奇偶校验码 3.1.2 CRC&#xff08;循环冗余校验&#xff09;校验码 3.2 纠错编码 3.2.1 海明校验码…

Materials Studio MS2020在linux系统上的安装包下载地址 支持centos Ubuntu rocky等系统

下载地址&#xff1a;MS2020-linux官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 Materials Studio 2020是一款功能强大的材料科学计算模拟软件&#xff0c;以下是其详细介绍&#xff1a; 核心模块功能 CASTEP模块&#xff1a;采用平面波赝势方法&#xff0c;适用于周…

JSON Schema 入门指南:如何定义和验证 JSON 数据结构

文章目录 一、引言二、什么是 JSON Schema&#xff1f;三、JSON Schema 的基本结构3.1 基本关键字3.2 对象属性3.3 数组元素3.4 字符串约束3.5 数值约束 四、示例&#xff1a;定义一个简单的 JSON Schema五、使用 JSON Schema 进行验证六、实战效果6.1 如何使用 七、总结 一、引…

初探Ollama与deepseek

什么是Ollama&#xff1f;它与大模型有什么联系&#xff1f; 简单说&#xff0c;Ollama就像是你电脑上的一个 “大模型小助手”。 以前&#xff0c;很多强大的大语言模型&#xff0c;比如能回答各种问题、写文章、翻译等的那些模型&#xff0c;要么只能在网上的服务器上用&am…

【word】保存重开题注/交叉引用消失,全局更新域问题

目录 一、更新域是什么二、更新域常见问题及解决方法&#xff08;一&#xff09;更新域后内容未变化&#xff08;二&#xff09;域代码显示异常&#xff08;三&#xff09;交叉引用无法更新&#xff08;四&#xff09;全选更新域出现错误 三、交叉引用与题注的关系及操作&#…

区块链中的数字签名:安全性与可信度的核心

数字签名是区块链技术的信任基石&#xff0c;它像区块链世界的身份证和防伪标签&#xff0c;确保每一笔交易的真实性、完整性和不可抵赖性。本文会用通俗的语言&#xff0c;带你彻底搞懂区块链中的数字签名&#xff01; 文章目录 1. 数字签名是什么&#xff1f;从现实世界到区块…

人工智能之数学基础:矩阵的范数

本文重点 在前面课程中,我们学习了向量的范数,在矩阵中也有范数,本文来学习一下。矩阵的范数对于分析线性映射函数的特性有重要的作用。 矩阵范数的本质 矩阵范数是一种映射,它将一个矩阵映射到一个非负实数。 矩阵的范数 前面我们学习了向量的范数,只有当满足几个条…

【MySQL】数据库初识

目录 一、什么是数据库 与数据结构的区别 各类软件&#xff08;数据库&#xff09;代表 关系型 vs 非关系型 关系型数据库 非关系型数据库 二、初识MySQL数据库 三、MySQL数据库安装 四、常用数据类型 内存 vs 硬盘 数值类型 字符串类型 日期类型 五、MySQL数据库…

Minio文件存储及Springboot集成

文章目录 Minio简介Minio安装使用下载Minio.exe启动访问WebUI MinIO基本概念Spingboot集成Minio设置本地Minio访问秘钥创建文件存储bucket项目pom.xml添加依赖配置文件修改Minio配置类Minio工具类定义HttpStatus定义统一返回结果定义controller类 总结 Minio简介 MinIO 是高性…

P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用

P8651 [P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用 题目 分析代码 题目 分析 代码中巧妙的用到3重循环&#xff0c;完美的解决了输出的顺序问题【题目要求从小到大】 需要注意的是2月的值&#xff0c;在不同的年份中应该更新2月的值 还有…

蓝桥杯练习代码

一、最接近的三数之和 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4], targe…

Go中slice和map引用传递误区

背景 关于slice和map是指传递还是引用传递&#xff0c;很多文章都分析得模棱两可&#xff0c;其实在Go中只有值传递&#xff0c;但是很多情况下是因为分不清slice和map的底层实现&#xff0c;所以导致很多人在这一块产生疑惑&#xff0c;下面通过代码案例分析slice和map到底是…

DeepSeek如何快速开发PDF转Word软件

一、引言 如今&#xff0c;在线工具的普及让PDF转Word成为了一个常见需求&#xff0c;常见的PDF转Word工具有收费的WPS&#xff0c;免费的有PDFGear&#xff0c;以及在线工具SmallPDF、iLovePDF、24PDF等。然而&#xff0c;大多数免费在线转换工具存在严重隐私风险——文件需上…

perf(es5-widget): es5-widget.js文件优化时间戳生成逻辑

这个文件内部分代码逻辑推荐语法&#xff1a; cacheVersion widgetcfg.versionif (cacheVersion "time") {cacheVersion Date.now ? Date.now() : new Date().getTime(); } 改善优化 后续更新对应代码行 perf(es5-widget): 优化时间戳生成逻辑 将 "&quo…

【语法】C++中string类中的两个问题及解答

贴主在学习string类时遇到过两个困扰我的问题&#xff0c;今天拿出来给大家分享一下我是如何解决的 一、扩容时capacity的增长问题 在string的capacity()接口中&#xff0c;调用的是这个string对象的容量(可以存多少个有效字符)&#xff0c;而size()是调用的string对象现在有…

Android 应用开发中,证书、签名和加固简述

目录 一、应用证书&#xff08;Digital Certificate&#xff09; 二、应用签名&#xff08;APK Signing&#xff09; 三、应用加固&#xff08;Obfuscation & Protection&#xff09; 三者的关系与协同 实际应用场景 总结 四、V1、V2、V3 签名方案的区别 1. V1 签名…

SpringMVC学习(初识与复习Web程序的工作流程)(1)

目录 一、SpringMVC(框架)的简要概述。 &#xff08;1&#xff09;SpringMVC与Servlet。 &#xff08;2&#xff09;技术方向。 &#xff08;3&#xff09;最终学习目标。 二、Web程序的基本工作流程。 &#xff08;1&#xff09;工作流程。 <1>浏览器。前后端任务。 <…

yunedit-post ,api测试比postman更好

postman应该是大家最熟悉的api测试软件了&#xff0c;但是由于它是外国软件&#xff0c;使用它的高端功能注册和缴费都比较麻烦。生成在线文档分享也经常无法访问被拦截掉。 这里可以推荐一下yunedit-post&#xff0c;该有的功能都有。 https://www.yunedit.com/postdetail …