Java学习day04: 方法和数组

发布时间 2023-07-15 21:05:44作者: 绿萝佛裳

我在B站上大学?

学习至:狂神说Java

1. 方法

1.1 方法的定义

  • 方法是语句的集合,它们在一起执行一个功能

    • 方法是解决一类问题的步骤的有序组合

    • 方法包含于类或对象之中

    • 方法在程序中被创建,在其他地方被引用

  • 方法设计的原则:保持方法的原子性,即一个方法只完成一个功能

  • 方法包含一个方法头和一个方法体。

    • 修饰符:不固定,告诉编译器如何调用该方法。定义了该方法的访问类型。

    • 返回值类型:返回数据的类型,如int、string等,可有可无,没有返回值是用void 。有时在方法体的结尾用return返回,此外return有终止方法体的作用

    • 方法名:方法名和参数共同构成方法签名,方法名尽量见名知道意。

    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数,这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和个数。参数是可选的,方法可以不包含任何参数。

      • 形式参数:在方法被调用时用于接收外界输入的数据

      • 实参:调用方法时实际传给方法的数据

        public class Demo01 {
            public static void main(String[] args) {
                //实际参数
                int sum = add(1, 2);//这个1,2就是实参
        
                System.out.println(sum);
            }
        
                //加法
                // 形参:用来定义作用的,这里的a, b就是形参
                public static int add(int a,int b){
                    return a + b;
                }
        }
        
    • 方法体:方法体包含具体的语句,定义该方法的功能。

  • 语法:

    [访问修饰符] 返回值类型 方法名(参数类型 形式参数名){
    ...; //方法体
    return 返回值;
    }
    

1.2 方法的调用

  • 在类内部,不同方法间可以相互调用;

  • 要调用某一类中的非静态方法,需要通过其对象调用;

  • 调用静态方法,通过类名来调用;

1.3 方法的重载

同一个方法名可以提供多种代码实现(方法体);

前提:形参列表不能完全一样

  • 个数
  • 形参类型
  • 参数排序(不同类型时)

被重载的方法必须具有不同的参数列表。不能基于不同修饰符或返回值类型来重载方法;

有时调用一个方法时,会有两个或者更多可能的匹配,但是编译器无法判断那个是最精确的匹配,这称为:歧义调用,编译时会报错

public class Demo01 {
    public static void main(String[] args) {

        double sum = add(1.1, 2);
        int sum1 = add(8, 9);
        double sum2 = add(8.9, 9.8);

        System.out.println(sum);
        System.out.println(sum1);
        System.out.println(sum2);
    }
        //,传递的参数为两个整数时调用
        public static int add(int a,int b){
            return a + b;
        }

        //方法重载, 传递参数为两个double类型, 或者一个整型一个double时调用
        public static double add(double a,double b){
            return a + b;
        }
}
3.1
17
18.700000000000003

进程已结束,退出代码0

注:这里计算出问题很正常

​ 计算机根本就不能精确地表示很多数,比如0.1这个数。计算机是用一种二进制格式存储小数的,这个二进制格式不能精确表示0.1,它只能表示一个非常接近0.1但又不等于0.1的一个数。数字都不能精确表示,在不精确数字上的运算结果不精确也就不足为奇了。

​ 解决办法:如果真的需要比较高的精度,一种方法是将小数转化为整数进行运算,运算结束后再转化为小数;另一种方法是使用十进制的数据类型,这个并没有统一的规范。在Java中是BigDecimal;

转载至:[double类型相加出错,原因详解,解决办法]((6条消息) double类型相加出错,原因详解,解决办法_double类型小数相加出现误差_摇滚侠的博客-CSDN博客)

1.4 可变参数

可传递同类型的可变参数给一个方法(多个同类型的形参); 可变参数的本质是数组。相当于传入了一个数组。

使用方法:在方法声明时,在指定参数类型后加一个省略号(...)

注意:一个方法只能指定一个可变参数,且必须是方法的最后一个参数,其他普通参数必须在他之前申明。

可变参数的本质是数组。相当于传入了一个数组

语法:

public void func(int...x){ //调用时可以写入多个int类型的数据
...;
}

eg:

public class Demo02 {
    public static void main(String[] args) {
        printMax(1.2, 2.3, 3.4, 5.6, 8.9, 9);

    }
    public static void printMax(double...x){
        if (x.length==0){
            System.out.println("没有传递参数");
        }
        double max = x[0];
        for(int i = 1;i < x.length; i++){
            if (x[i] >max){
                max = x[i];
            }
        }
        System.out.println("最大值为:"+ max);

    }
}
最大值为:9.0

进程已结束,退出代码0

1.5 递归

不断调用自身,所以必须定义好出口,不然会陷入无限调用;

递归采用的是栈机制,递归次数不宜过大。

递归结构包括两个部分:

  • 递归头(边界条件):什么时候不调用自身方法。如果没有递归头,将陷入死循环。

  • 递归体:什么时候需要调用自身方法。

eg:

阶乘计算:

public static int factorial(int num){
    if(num==1){
        return 1;
    }
    else{
        return num*factorial(num-1);
    }
}

例题

用方法调用的方式写一个简易计算器

import java.util.Scanner;

public class Demo03 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入第一个数字: ");
        double num1 = scanner.nextDouble();

        System.out.print("请输入运算符(+, -, *, /): ");
        char operator = scanner.next().charAt(0);

        System.out.print("请输入第二个数字: ");
        double num2 = scanner.nextDouble();

        calculator(num1, operator, num2);

    }
    public static void calculator(double num1, char x, double num2){

        double result = 0.0 ;

        switch (x) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 == 0) {
                    System.out.println("错误:除数不能为零");
                    return;
                }
                result = num1 / num2;
                break;
            default:
                System.out.println("错误:无效的运算符");
                return;
        }
        System.out.println("结果为:" + result);
    }
}
请输入第一个数字: 2
请输入运算符(+, -, *, /): +
请输入第二个数字: 3
结果为:5.0

进程已结束,退出代码0
请输入第一个数字: 2
请输入运算符(+, -, *, /): /
请输入第二个数字: 0
错误:除数不能为零

进程已结束,退出代码0
请输入第一个数字: 2
请输入运算符(+, -, *, /): a
请输入第二个数字: 2
错误:无效的运算符

进程已结束,退出代码0

2. 数组

2.1 数组的定义

  • 数组是相同类型数据的有序集合
  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
  • 其中,每一个数据作为一个数组元素,每个数组元素可以通过下标来访问它
  • 数组的基本特点
    • 长度确定。数组一旦被创建,他的大小就是不可改变的
    • 元素类型必须相同
    • 数组中的元素类型可以是任何数据类型,包括基本类型和引用类型
    • 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素都相当于该对象的成员变量。

2.2 数组的声明与创建

  • 数组的声明(仅声名)
数据类型[] 数组名;
  • 数组的声明和创建

    声明时创建

数据类型[] 数组名 = new 数据类型[数组长度];

或
    
数据类型 数组名[] = new 数据类型[元素个数];  (不推荐) 

​ 声明后创建

数据类型[] 数组名;
数组名 = new 数据类型[数组长度];
  • 数组的初始化
// 创建时初始化
数据类型[] 数组名 = new 数据类型[]{元素值1,元素值2,元素值3,...};
数据类型[] 数组名 = {元素值1,元素值2,元素值3,...}; // 创建时初始化的简写形式

// 先声明后初始化
数据类型[] 数组名a;
数组名a = new 数据类型[]{元素值1,元素值2,元素值3,...};

// 先创建后初始化
数据类型[] 数组名 = new 数据类型[数组长度];
数组名[0] = 元素值1;
数组名[1] = 元素值2;
...

注:

静态初始化时,使用new xxx[]时不能指定数组的大小

int[] arrays = new int[]{1,2,3}; //正确
int[] arrays = new int[3]{1,2,3}; //错误
int[] arrays = {1,2,3}; //正确

动态初始化:只指定个数的大小、初始化工作由系统为我们完成,数组的每个位置上的值都由系统 来初始化、使用默认的值

int[] arrays = new int[5]; //此时arrays中所有元素为0

eg:

public class ArrayDemo01 {
    public static void main(String[] args) {

        // 数组的声明和创建
        int[] array; // 仅声明
        int[] array1 = new int[3];
        int array2[] = new int[5];  //不推荐

        // 创建时初始化
        int[] array3 = new int[]{1,2,3};//
        int[] array4 = {1,2}; // 创建时初始化的简写形式

        // 先声明后初始化
        int[] array5;
        array5 = new int[]{0,1};

        // 先创建后初始化
        int[] array6 = new int[2];
        array6[0] = 1;
        array6[1] = 2;

    }
}

2.3 内存分析

在Java中,内存分为几个不同的区域,其中最重要的是堆(heap)和栈(stack)。除此之外,还有方法区(Method Area)和程序计数器(Program Counter)。

  1. 堆(heap):堆是Java中用于存储对象实例的区域。所有通过关键字“new”创建的对象都存储在堆中。堆的大小可以通过“Xmx”和“Xms”参数来设置。当创建一个对象时,堆会分配一块足够大的内存来存储对象的实例变量,并返回一个指向该内存区域的引用。

  2. 栈(stack):栈是Java中用来存储方法调用和局部变量的区域。每当调用一个方法时,Java虚拟机会分配一个称为“栈帧(stack frame)”的数据结构,用于存储方法的参数和局部变量。栈的大小是固定的,由虚拟机在启动时设定。

  3. 方法区(Method Area):方法区是用于存储类信息、常量、静态变量等的区域。它在Java虚拟机启动时被创建,并且会随着加载类和接口的过程而不断增长。Java 8之前,方法区是永久代(Permanent Generation)的一部分,从Java 8开始,方法区被移到了元空间(Metaspace)。

  4. 程序计数器(Program Counter):程序计数器是一块内存区域,它存储着当前线程执行的字节码指令的地址。在任何时候,一个线程都只有一个活动的方法,程序计数器会指向当前方法正在执行的字节码指令。

注:问的chat-gpt ?

2.4 数组的使用

可以通过元素索引值来访问数组的指定元素值,数组的索引是从0开始的,索引值超出范围时会报错(边界溢出);

eg1:

public class ArrayDemo02 {
    public static void main(String[] args) {
        int sum = 0;
        int[] nums = new int[]{1,2,3,4,5,6,7,8,9,10};
        for (int x : nums){
            sum += x;
        }
        System.out.println("数组中所有元素的和为: "+ sum);

    }
}
数组中所有元素的和为: 55

进程已结束,退出代码0

注:遍历变量的数据类型需要和数组声明的变量类型保持一致

​ 增强型For循环的快捷输入方式:数组名 . for

eg2 数组作为方法入参:

public class ArrayDemo03 {
    public static void main(String[] args) {

        int[] nums = new int[]{1,2,3,4,5,6,7,8,9,10};
        printArray(nums);

    }
    //打印数组元素
    public static  void printArray(int[] nums){
        for (int i = 0; i < nums.length; i++) {
            System.out.println("nums["+i+"] = "+ nums[i]);

        }
    }
}
nums[0] = 1
nums[1] = 2
nums[2] = 3
nums[3] = 4
nums[4] = 5
nums[5] = 6
nums[6] = 7
nums[7] = 8
nums[8] = 9
nums[9] = 10

进程已结束,退出代码0

eg3 数组作为返回值:

public class ArrayDemo04 {
    public static void main(String[] args) {

        int[] nums = new int[]{1,2,3,4,5,6,7,8,9,10};
        int[] invertNums = invertArray(nums);
        printArray(invertNums);

    }
    //反转数组
    public static int[] invertArray(int[] nums){
        int[] result = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            result[i] = nums[nums.length-i-1];
        }
        return result;
    }
    //打印数组元素
    public static  void printArray(int[] nums){
        for (int i = 0; i < nums.length; i++) {
            System.out.println( nums[i]);
        }
    }
}
10
9
8
7
6
5
4
3
2
1

进程已结束,退出代码0

2.5 多维数组

在Java中,多维数组是指数组的数组,也就是数组中的每个元素也是一个数组。Java支持二维、三维甚至更高维度的数组。多维数组可以用于表示表格、矩阵、图像等具有多个维度的数据结构。

1.二维数组:二维数组是最常见的多维数组形式。它是由行和列组成的网格结构。声明一个二维数组需要指定行数和列数,并可以通过索引访问特定的元素。例如:

int[][] matrix = new int[3][4];
matrix[0][0] = 1;
matrix[1][2] = 3;
int value = matrix[2][3]; // 访问第三行第四列的元素

2.三维数组:三维数组是由多个二维数组组成的。它是一个由平面网格组成的立体结构。声明一个三维数组需要指定长、宽和高,并可以通过索引访问特定的元素。例如:

int[][][] cube = new int[3][4][5];
cube[0][1][2] = 42;
int value = cube[2][3][4]; // 访问第三层第四行第五列的元素

3.更高维度的数组:Java还支持更高维度的数组,原理类似。可以根据需求声明和使用具有更多维度的数组。

注:

多维数组在声明和初始化时需要指定每个维度的大小。每个维度的大小可以是不同的,也可以是相同的。对于大型的多维数组,可以使用循环和嵌套来遍历和操作数组元素。
此外,Java中也支持使用简化的语法来声明和初始化多维数组

int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

这样可以直接指定数组的初始值,而不必显式指定数组的大小。
多维数组在处理一些复杂的数据结构时非常有用,但在使用时应该小心处理索引,以避免数组越界错误。

eg:

public class ArrayDemo05 {
    public static void main(String[] args) {
        int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int x = 0;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + "\t");
                x++;
                if (x % 3 ==0){
                    System.out.println();
                }

            }

        }
    }
}
1	2	3	
4	5	6	
7	8	9	

进程已结束,退出代码0

2.6 Arrays 类

在Java中,java.util.Arrays 类提供了一些用于操作数组的静态方法。这些方法可以用于数组的排序、搜索、拷贝、填充等常见操作。

一些Arrays类的常用方法:

1.排序方法:

sort(array);//对数组进行升序排序
sort(array, comparator);//使用自定义的比较器对数组进行排序

2.搜索方法:

binarySearch(array, key);//在已排序的数组中使用二分查找算法查找指定的元素,并返回其索引
binarySearch(array, fromIndex, toIndex, key);//指定搜索范围进行二分查找

3.数组拷贝方法:

copyOf(original, newLength);//将原始数组复制到一个新的数组中,新数组的长度可以比原数组长或短
copyOfRange(original, from, to);//将原始数组的指定范围复制到一个新的数组中

4.数组填充方法:

fill(array, value);//将数组的所有元素都填充为指定的值
fill(array, fromIndex, toIndex, value);//将数组的指定范围的元素填充为指定的值

5.数组转换方法:

toString(array);//返回数组的字符串表示形式
deepToString(array);//返回多维数组的字符串表示形式

6.数组比较方法:

equals(array1, array2);//比较两个数组是否相等
deepEquals(array1, array2);//比较两个多维数组是否相等

注:

Arrays类的方法都是静态方法,因此不需要创建该类的实例即可使用这些方法。使用import java.util.Arrays;语句导入类后,可以直接通过类名访问这些方法。(使用格式:Arrays.xxx) 注意格式,大部分都是只适用于一维数组。

2.7 冒泡排序

冒泡排序:通过多次交换相邻元素的位置来实现排序。在每一轮的比较中,如果相邻元素的顺序错误,则交换它们的位置,使较大或较小的元素逐渐向数组的末尾冒泡。

eg:冒泡升序

public class ArrayDemo06 {
    public static void main(String[] args) {
        int[] nums = {5, 2, 8, 12, 1, 6};

        System.out.println("排序前的数组:");
        printArray(nums);

        // 冒泡升序
        bubbleSort(nums);

        System.out.println("排序后的数组:");
        printArray(nums);
    }

    public static void bubbleSort(int[] array) {
        int n = array.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (array[j] > array[j + 1]) {//降序只需将 > 换成 <
                    // 交换相邻元素的位置
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }

    public static void printArray(int[] array) {
        for (int num : array) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
排序前的数组:
5 2 8 12 1 1 2 7 66 
排序后的数组:
1 1 2 2 5 7 8 12 66 

进程已结束,退出代码0

2.8 稀松数组

稀疏数组是一种特殊的数组形式,用于表示大部分元素值相同或者为默认值的数组。在稀疏数组中,只记录非默认值元素的行、列和值,从而节省存储空间。

在Java中,可以使用二维数组来表示稀疏数组。通常,稀疏数组的行数固定为3,列数固定为非默认值元素的个数加1。

具体的表示形式如下:

稀疏数组:
row   col        value
-----------------------------
n      n    non-default value
n      n    non-default value
n      n    non-default value
...

eg:

public class ArrayDemo07 {
    public static void main(String[] args) {
        int[][] array1 = {
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ,
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0}
        };

        System.out.println("原始数组为: ");
        printArray(array1);
        System.out.println("其稀松数组为: ");
        printArray( sparseArray(array1) );
        System.out.println("还原稀松数组为: ");
        printArray( revertSparseArray( sparseArray(array1) ) );

    }
    //打印
    public static void printArray(int[][] x){
        for (int i = 0; i < x.length; i++) {
            for (int y: x[i]) {
                System.out.print(y + "\t");
            }
            System.out.println();
        }
    }

    //统计数组有效数据
    public static int count(int[][] x){
        int sum = 0;
        for (int i = 0; i < x.length; i++) {
            for (int j = 0; j < x[i].length; j++) {
                if (x[i][j] !=0 ){
                    sum++;
                }
            }
        }
        return sum;
    }

    //稀松数组
    public static int[][] sparseArray(int[][] x){
        int sum = count(x);
        int c =0;
        int d =-1;
        int e =-1;
        int[][] y = new int[sum + 1][3];
        y[0][0] = x.length;
        y[0][1] = x[0].length;
        y[0][2] = sum;
        for (int a = 0; a < x.length; a++) {
            d++;
            for (int b = 0; b < x[a].length; b++) {
                e++;
                if (x[a][b]!=0){
                    c++;
                    y[c][0] = d;
                    y[c][1] = e;
                    y[c][2] = x[a][b];
                }
            }
            e = -1;
        }
      return y;
    }

    //还原稀松数组
    public static int[][] revertSparseArray(int[][] x){
        int[][] y = new int[x[0][0]][x[0][1]];
        for (int i = 1; i < x.length; i++) {
                y[x[i][0]][x[i][1]] = x[i][2];
        }
        return y;
    }
}
原始数组为: 
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	1	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	3	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	4	0	0	
其稀松数组为: 
12	12	4	
1	2	1	
4	5	2	
8	7	3	
11	9	4	
还原稀松数组为: 
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	1	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	2	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	3	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	4	0	0	

进程已结束,退出代码0

3. 练习题

1.输入三角形层数n(正整数,不建议太大),打印如下图所示的倒立n层三角形;要求:需要做输入防错(x>0,x需要是整数)。

image-20230715135637446

import java.util.Scanner;
public class test01 {
    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);

            // 输入层数并进行防错处理
            int n = 0;
            boolean isValidInput = false; //用于判断是否为有效输入

            while (!isValidInput) {
                System.out.print("请输入正整数n(建议不要太大)表示三角形的层数: ");
                String input = scanner.nextLine();
                try {
                    n = Integer.parseInt(input);//判断输入是否为整数
                    if (n > 0) {
                        isValidInput = true;//循环出口
                    } else {
                        System.out.println("输入错误,请输入大于0的正整数!");
                    }
                }
                catch (NumberFormatException e) {
                    System.out.println("输入错误,请输入大于0的正整数!");
                }
            }

            // 打印倒立三角形
            printInvertedTriangle(n);

            scanner.close();//关闭键盘输入
    }

        public static void printInvertedTriangle(int n) {
            for (int i = n; i >= 1; i--) {
                // 打印空格
                for (int j = 0; j < n - i; j++) {
                    System.out.print("  ");
                }

                // 打印星号
                for (int j = 0; j < 2 * i - 1; j++) {
                    System.out.print("* ");
                }

                System.out.println();
            }
        }
}
请输入正整数n(建议不要太大)表示三角形的层数: 6.7
输入错误,请输入大于0的正整数!
请输入正整数n(建议不要太大)表示三角形的层数: -5.2
输入错误,请输入大于0的正整数!
请输入正整数n(建议不要太大)表示三角形的层数: -5
输入错误,请输入大于0的正整数!
请输入正整数n(建议不要太大)表示三角形的层数: asd
输入错误,请输入大于0的正整数!
请输入正整数n(建议不要太大)表示三角形的层数: 10
* * * * * * * * * * * * * * * * * * * 
  * * * * * * * * * * * * * * * * * 
    * * * * * * * * * * * * * * * 
      * * * * * * * * * * * * * 
        * * * * * * * * * * * 
          * * * * * * * * * 
            * * * * * * * 
              * * * * * 
                * * * 
                  * 

进程已结束,退出代码0

2.编写一个方法,计算一个整数各位数字之和。例如:输入234返回9 ,即(2+3+4)。

import java.util.Scanner;
public class test02 {
    public static void main(String[] args) {
        System.out.println("此程序用于计算一个整数各位数字之和");
        Scanner scanner = new Scanner(System.in);

        //防错处理
        long n = 0;
        boolean isValidInput = false; //用于判断是否为有效输入

        while (!isValidInput) {
            System.out.print("请输入整数n: ");
            String input = scanner.nextLine();
            try {
                n = Integer.parseInt(input);//判断输入是否为整数
                System.out.print(n + "的各位数字的和为: ");
                if (n < 0){
                    n= -n;//负数取反
                }
                isValidInput = true;
            }
            catch (NumberFormatException e) {
                System.out.println("输入错误,请输入整数!");
            }
        }

        System.out.println(sumDigits(n));//调用函数
    }

    //方法: 计算一个整数各位数字之和
    public static int sumDigits(long n){
        String strNummber = String.valueOf( n );
        int x = strNummber.length();//计算数的位数
        int sum = 0;
        int y = 1;
        for (int i = 1; i <= x; i++) {
            for (int j = x; j > i; j--) {
                y *= 10;
            }
            sum += n/(y);
            n = n%y;
            y = 1;
        }
        return sum;
    }
}
此程序用于计算一个整数各位数字之和
请输入整数n: asf
输入错误,请输入整数!
请输入整数n: 2.5
输入错误,请输入整数!
请输入整数n: -5678
-5678的各位数字的和为: 26

进程已结束,退出代码0

3.非回文的反素数是指一个将其逆向之后也是一个素数的非回文数。 例如:17逆序后与原来不相等,且17和71均是素数,所以17和71是非回文的反素数。编写程序,显示从10开始的前100个非回文的反素数,每行显示10个。

public class test03 {
    public static void main(String[] args) {
        int x = 0;
        System.out.println("10开始的前100个非回文的反素数(每行显示10个)如下:");
        for (int j =10 ;  ; j++){
            if ( primeNumberJudgment(j) &&
                 primeNumberJudgment( reverseNumber(j)) &&
                 reverseNumber(j) != j ){//判断是否是非回文的反素数,非回文指逆序后与原来不相等
                if (j < 1000){
                    System.out.print(j + "\t\t");
                }
                else {
                    System.out.print(j + "\t");
                }
                x++;
                if (x%10==0){
                    System.out.println();//10的倍数后换行
                }
            }
            if (x >=100){
                break;//循环出口
            }
        }


    }

    //素数判断
    public static boolean primeNumberJudgment(int x){
        for(int i = 2;i <= x/2;i++){//比一个数的0.5倍大的数不可能是该数的因数
            if(x % i==0){
                return false;//2~x/2中发现x的一个因数即可证明非素数
                }
            }
        return true;
    }

    //整数逆序
    public static int reverseNumber(int x){
        int m = 0;
        String strNumber = String.valueOf( x );//使用 String 类的 valueOf()方法将数字转成字符串

        StringBuilder reversed = new StringBuilder(strNumber).reverse();//使用StringBuilder类提供的方法,反转字符串
        String reverseStrNumbers = reversed.toString();

        m = Integer.parseInt( reverseStrNumbers );//判断字符串是否为纯数字组成,若是转成整型
        return m;
    }
     /*整数逆序自定义算法
     public static int reverseNumber(int x){
        String strNum = Integer.toString(x);//整数转字符串
        int m = strNum.length();//计算字符串长度
        int n = 0;//用于储存逆序后的数
        int y = 1;//用于计算位权重
        int z = m-1;用于计算逆序后位权重
        for (int i = 1; i <= m; i++) {
            for (int j = m; j > i; j--) {
                y *= 10;
                z--;
            }
            n += (x/y)* Math.pow(10, z);
            x = x%y;//依次去掉最高位
            y = 1;  //y, z值重置
            z=m-1;
        }
        return n;
     }//返回逆序后的数

         */

}
10开始的前100个非回文的反素数(每行显示10个)如下:
13		17		31		37		71		73		79		97		107		113		
149		157		167		179		199		311		337		347		359		389		
701		709		733		739		743		751		761		769		907		937		
941		953		967		971		983		991		1009	1021	1031	1033	
1061	1069	1091	1097	1103	1109	1151	1153	1181	1193	
1201	1213	1217	1223	1229	1231	1237	1249	1259	1279	
1283	1301	1321	1381	1399	1409	1429	1439	1453	1471	
1487	1499	1511	1523	1559	1583	1597	1601	1619	1657	
1669	1723	1733	1741	1753	1789	1811	1831	1847	1867	
1879	1901	1913	1933	1949	1979	3011	3019	3023	3049	

进程已结束,退出代码0

4.使用下面的方法头编写方法,消除数组中重复出现的值;

public static int[] eliminateDuplicates(int[]numbers)
public class test04 {
    public static void main(String[] args) {
        int[] x ={1, 2 ,5, 6, 9, 0, -28, 4, 1, 2, 5, 7, 9, 23, 45, 56, 78,28, 4, 1, 2, 5, 7, 1, 5 ,7};
        System.out.println("原数组为:");
        printArray(x);
        System.out.println("去重并升序排列后的数组:");
        printArray( eliminateDuplicates(x) );
    }

    //数组去重
    public static int[] eliminateDuplicates(int[] numbers){
        bubbleSort(numbers);//数组升序
        int n = 0;//用于统计重复数字
        int y = numbers.length;//计算数组长度
        for (int i = 0; i < y-1; i++) {//统计重复数字个数
            if (numbers[i]==numbers[i+1]){
                n++;
            }
        }
        int[] newArray = new int[y-n];//定义新数组用于存放升序后的去重数组
        int a = 0;//用于数组赋值,下标错位问题
        for (int i = 0; i < y-1; i++) {//新数组赋值
            if (numbers[i] != numbers[i+1]){
                newArray[a] = numbers[i];
                a++;
            }
            if (a==y-n-1){//用于判断最后一位
                newArray[y-n-1]  = numbers[y-1];
            }

        }
        return newArray;
    }
    //冒泡升序
    public static void bubbleSort(int[] array) {
        int n = array.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    // 交换相邻元素的位置
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
    //打印数组
    public static void printArray(int[] x){
        System.out.print("[");
        for (int i =0; i < x.length-2;i++) {
                System.out.print(x[i] + ", ");
        }
        System.out.println(x[x.length-1] + "]");
    }
}
原数组为:
[1, 2, 5, 6, 9, 0, -28, 4, 1, 2, 5, 7, 9, 23, 45, 56, 78, 28, 4, 1, 2, 5, 7, 1, 7]
去重并升序排列后的数组:
[-28, 0, 1, 2, 4, 5, 6, 7, 9, 23, 28, 45, 78]

进程已结束,退出代码0