Java基础

Java基础

java的应用

java分为三个版本 javaSE javaEE javaME

  • javaSE 是java语言的标准版,可用于桌面端的开发,是其他两个版本的基础
  • javaEE 是java语言的企业版,可用于web方向的网站开发,如web开发、分布式开发、移动开发等
  • javaME 是java语言的小型版,可用于嵌入式电子系统,如手机、平板等

数据类型

在Java中,数据类型分为基本数据类型和引用数据类型,它们在存储方式、默认值、内存分配和使用场景等方面有显著区别。

基本数据类型

Java中一共有四类八种基本数据类型

类型
整数类型byte short int long
浮点类型float double
字符类型char
布尔类型boolean
除掉这四类八种基本类型,其它的都是对象,也就是引用类型,包括数组。

整数数据类型(取值范围不同)常用 int

  • byte (取值范围为:-128~127)
  • short (取值范围为:-32768~32767)
  • int (取值范围为:-2147483648~2147483647)
  • long (取值范围为:-9223372036854775808~9223372036854775807)

    注意:

    long类型数据需要加L或l作为后缀

浮点数(小数类型常用 double)

  • float (取值范围为:-3.4028235E38~3.4028235E38)
  • double (取值范围为:-1.7976931348623157E308~1.7976931348623157E308)

    注意:

    float类型数据需要加F或f作为后缀

字符

  • char (取值范围为:0~65535)

    拓展

    小数和整数数据类型取值范围:double>float>int>long>short>byte

布尔值

  • boolean (取值为:true、false)

引用数据类型

  • 引用类型定义的变量非常类似于C/C++的指针,它内部存储一个“地址”,可以指向一个对象在内存中的位置。
  • 引用数据类型有类(class)、接口(interface)、数组(array)、枚举(enum)等。
  • 基本数据类型是直接存储值,而引用数据类型是存储指向对象的引用。
  • 基本数据类型的默认值是0false,而引用数据类型的默认值是null

基本数据类型包装类

  • ByteShortIntegerLongFloatDoubleBooleanCharacterString 是基本数据类型的包装类,是引用数据类型。
包装类的主要用途:
  1. 对象化:包装类允许将基本数据类型作为对象使用,例如在集合(如 ArrayList )中存储基本数据类型。
  2. 实用方法:包装类提供了许多静态方法,例如 parseInt()valueOf() 等,用于转换和操作数据。
  3. 自动装箱与拆箱:Java支持自动装箱(将基本数据类型自动转换为包装类对象)和拆箱(将包装类对象自动转换为基本数据类型)。

注意

进行计算时使用的数据类型

  • 选择使用基本数据类型还是包装类取决于具体的场景和需求

基本数据类型计算优点

  • 基本数据类型计算性能高 基本数据类型直接存储在栈内存中,操作速度快,内存占用小。
  • 基本数据类型计算效率高 适合大量数值计算或循环操作,避免了对象的创建和垃圾回收开销。 基本数据类型计算缺点
  • 由于集合中不能存储基本数据类型,因此不能作为泛型 不能直接用于 List<int> ,必须使用 List<Integer>
  • 缺少包装类提供的实用方法(如 parseInt()valueOf()toString() 等)。

包装类计算优点

  • 对象特性:可以用于泛型、集合(如 List<Integer> )或需要对象的地方。
  • 功能丰富:提供了许多实用方法(如 Integer.parseInt()Double.compare() 等)。
  • 支持 null 值:可以表示缺失值(如数据库中的 NULL )。

包装类计算缺点

  • 性能较低:包装类是对象,存储在堆内存中,操作速度较慢,且有额外的内存开销。
  • 自动装箱/拆箱开销:频繁的装箱和拆箱操作会影响性能。(包装类的计算最终都会转化为基本数据类型的计算)
  • 使用 Integer 的循环比直接使用 int 慢数倍
long startTime = System.nanoTime();
Integer sum = 0;
for (int i = 0; i < 1000000; i++) {
    sum += i; // 每次循环都会拆箱和装箱
}
long endTime = System.nanoTime();
System.out.println("Time taken: " + (endTime - startTime) + " ns");

处理数字精度的数据类型

  • BigDecimal(高精度数据类型) 是 Java 中用于精确计算的高精度数值类型,特别适合处理金融、货币等需要避免浮点数精度误差的场景。

为什么需要BigDecimal

  1. 浮点数精度问题
System.out.println(0.1 + 0.2); // 输出 0.30000000000000004
  • float/double 基于 IEEE 754 标准,无法精确表示所有十进制小数,会导致金额计算等场景出现精度丢失
  1. BigDecimal 优势
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
System.out.println(a.add(b)); // 精确输出 0.3

创建 BigDecimal 的正确方式

// 1. 字符串构造(最安全)
BigDecimal d1 = new BigDecimal("0.1"); 

// 2. 使用 valueOf(内部调用 toString)
BigDecimal d2 = BigDecimal.valueOf(0.1); 

注意

  • 浮点数构造会带入精度误差!
  • BigDecimal d3 = new BigDecimal(0.1);
  • 实际值可能是 0.100000000000000005551115...

基本运算与精度控制

  1. 四则运算(返回新对象)
BigDecimal num1 = new BigDecimal("10");
BigDecimal num2 = new BigDecimal("3");

BigDecimal sum = num1.add(num2);      // 加法: 13
BigDecimal diff = num1.subtract(num2); // 减法: 7
BigDecimal product = num1.multiply(num2); // 乘法: 30
  1. 除法必须指定精度和舍入模式

注意

除法必须指定舍入,否则遇到无限小数会抛出 ArithmeticException

// 错误:无限小数会抛出 ArithmeticException
// BigDecimal result = num1.divide(num2); 

// 正确:指定保留3位小数,四舍五入
BigDecimal quotient = num1.divide(num2, 3, RoundingMode.HALF_UP); // 3.333

//设置小数位数
BigDecimal num = new BigDecimal("3.14159");

// 保留两位小数(四舍五入)
BigDecimal scaled = num.setScale(2, RoundingMode.HALF_UP); // 3.14

// 直接截断
BigDecimal truncated = num.setScale(2, RoundingMode.DOWN); // 3.14(若为 3.149→3.14)

舍入模式

模式规则示例
HALF_UP四舍五入(常用)2.35 → 2.4
HALF_DOWN五舍六入2.35 → 2.3
HALF_EVEN银行家舍入(四舍六入五取偶)2.35 → 2.4,2.45 → 2.4
UP远离零方向舍入-1.1 → -1.2
DOWN向零方向舍入-1.1 → -1.0
CEILING向正无穷方向舍入1.1 → 2.0,-1.9 → -1.0
FLOOR向负无穷方向舍入1.9 → 1.0,-1.1 → -2.0
  1. 比较与相等性
  • 比较值大小(用 compareTo()
BigDecimal x = new BigDecimal("1.0");
BigDecimal y = new BigDecimal("1.00");
x.compareTo(y);  // 返回 0(数值相等)

这个方法返回一个整数,表示两个BigDecimal对象在数值上的大小关系。

  1. 返回 -1 表示当前对象小于参数对象。

  2. 返回 0 表示当前对象等于参数对象。

  3. 返回 1 表示当前对象大于参数对象。

  • 避免使用 equals()
x.equals(y); // false(因为精度不同:1.0的scale=1, 1.00的scale=2)

运算符

算数运算符

  • 加减乘除 + - * /

    注意

    除法运算符 /

    • 当运算符两边都是整数时,结果是整数
    • 除法运算符通常是向下取整
    • 当运算符两边都是小数时,结果是小数 :::
  • 取余 %

    注意

    在代码中如果有小数参与运算,结果可能是不精确的

隐式转换

在进行算数运算时,数据类型不一样不能直接进行计算,需转成一样的才能进行运算

算数运算符的隐式转换

算数运算符隐式转换的两种提升规则

  • 取值范围小的,和取值范围大的进行运算,小的会提升为大的,再进行运算
  • byte < short < int < long < float < double
  • byte、short、char 三种类型的数据在运算的时候,都会提升为int类型,然后再进行运算

字符串的“+”操作

  • 当“+”操作中出现字符串时,“+”是字符串连接符,而不是算数运算符了,会将前后数据进行拼接,并产生一个新的字符串
  • 连续进行“+”操作时,从左到右依次执行

字符的“+”操作

  • 当字符+字符或数字时,会将字符转换为对应的ASCII码,然后进行运算

自增自减运算符

  • a++ 先用再加
  • ++a 先加再用
  public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 1;
        System.out.println(a++);//1
        System.out.println(++b);//2
    }
}

赋值运算符

  • = 赋值
  • += 累加
  • -= 累减
  • *= 累乘
  • /= 累除
  • %= 累取余

    注意

    除等号运算符外 以上所有运算符都隐藏了一个强制类型转换

关系运算符

  • ==
  • !=
  • <
  • =

  • <= 比较运算符的结果都是boolean类型,要么是true要么是false

逻辑运算符

  • & 与
  • | 或
  • ^ 异或 相同返回false 不同返回true
  • ! 非 逻辑运算符当两边为数字时,会将两边的数字转为二进制进行与或运算

短路运算符

  • && 逻辑与
  • || 逻辑或

三元运算符

格式 :条件表达式?表达式1:表达式2

源码、反码、补码

源码

定义:十进制数据的二进制表现形式,最左边是符号位,符号位为0表示正数,符号位为1表示负数

反码

定义:源码的符号位取反,符号位为0表示正数,符号位为1表示负数 反码是解决源码不能计算负数而出现的

计算规则:

  • 正数的反码不变
  • 负数的反码在源码的基础上,符号位不变。数值取反,0变1,1变0

补码

补码的出现是为了解决负数计算跨0的问题而出现的
反码+1
一个字节的取值范围是-128~127
补码的计算规则

  • 正数的补码不变 负数的补码在反码的基础上+1
  • 补码还能多记录一个特殊值-128,该数据在1个字节下,没有源码和反码 补码注意点
  • 计算机中的存储和计算都是以补码的形式进行的

循环练习

求1~5之间的和

public class Test {
    public static void main(String[] args) {
        //1.求1-5之间的和
        int count = 0;
        for (int i = 1; i <= 5; i++) count += i;
        System.out.println(count);//15
    }
}

求1~100之间的偶数和

public class Test {
    public static void main(String[] args) {
        int count = 0;
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) count += i;
        }
        System.out.println(count);//2550
    }
}

键盘录入一个大于等于2的整数x,要求计算该整数的平方根

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int x = sc.nextInt();
        if (x < 2) throw new Error("请输入一个大于等于2的整数");
        int result = 0;
        while (result * result <= x) result++;
        System.out.println(result - 1);
    }
}

猜数字小游戏


import java.util.Random;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        int num = r.nextInt(100) + 1;
        Scanner sc = new Scanner(System.in);
        System.out.println("值为" + num);
        while (true) {
            System.out.println("请输入一个整数");
            int inputNum = sc.nextInt();
            if (inputNum > num) System.out.println("猜大了");
            else if (inputNum < num) System.out.println("猜小了");
            else {
                System.out.println("猜对了");
                break;
            }
        }
    }
}

数组

定义:是一种容器,可以用来存储同种数据类型的多个值

  • 数组容器在存储数据的时候,需要结合隐式转换考虑
  • int 类型的数组容器(boolean(不能)、byte(能)、short(能)、int(能)、double(不能) )
  • 建议 容器的类型和存储的数据类型保持一致

数组的定义

数组的静态初始化

  • 静态初始化以后数组长度不可变
  • 数组的元素类型必须和数组容器的类型一致
  • 格式:数据类型[] 数组名 = new 数据类型[数组长度]{数组元素1,数组元素2,数组元素3,...}
  • 简写格式:数据类型[] 数组名 = {数组元素1,数组元素2,数组元素3,...}
public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        //简写
        int[] arr2 = {1, 2, 3, 4, 5};
    }
}

地址值格式的含义

在定义数组以后,打印该数组发现是地址值

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        System.out.println(arr);//[I@1b6d3586
    }
}
  • [ 表示该地地址值存储一个数组
  • I 表示该地址值存储的是一个int类型数组
  • @ 表示一个间隔符号。(固定格式)
  • 1b6d3586 表示该地址值存储的数组的hash值(十六进制)
  • 平时我们习惯将这个整体叫做数组的地址值

数组元素的获取

格式 :数组名[下标值]

  • 数组下标从0开始
  • 数组下标不能超过数组长度

将数据存储到数组中

格式 :数组名[下标值] = 值

  • 一但覆盖后,原来的数据就不存在了

数组遍历

  • 数组遍历:遍历数组中的每一个元素
  • 格式:for(数据类型 变量名 : 数组名){}
public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        for (int i : arr) System.out.println(i);
    }
}

遍历数组并求和

public class Test {
    public static void main(String[] args) {
        int[] arr1 = {1, 2, 3, 4, 5};
        int count = 0;
        for (int j : arr1) count += j;
        System.out.println(count);
    }
}

统计数组里面一共有多少个能被3整除的数

 public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int count = 0;
        for (int i : arr) i % 3 == 0 && count++;
        System.out.println(count);
    }
}

数组的动态初始化

  • 初始化时只指定数组的长度,由系统为数组分配初始值
  • 格式:数据类型[] 数组名 = new 数据类型[数组长度];

数组默认初始化规律

  • 整数类型默认初始化值为0
  • 浮点类型默认初始化值为0.0
  • 布尔类型默认初始化值为false
  • 字符类型默认初始化值为\u0000 (空字符串)
  • 引用类型默认初始化值为null

遍历数组求和

需求:生成10个1~100的随机数存入数组

  • 求出所有数据的总和
  • 求出所有数据的平均数
  • 统计有多少个数据比平均值小
public class Test {
    public static void main(String[] args) {
        int[] arr = new int[10];
        int count = 0;
        Random r = new Random();
        for (int i : arr) {
            int num = r.nextInt(100) + 1;
            count += num;
            arr[i] = num;
        }
        //和
        System.out.println("和" + count);
        //平均值
        int average = count / arr.length;
        System.out.println("平均值" + average);
        //统计有多少个数据比平均值小
        int count1 = 0;
        for (int i : arr) if (i < average) count1++;
        System.out.println("总共有" + count1 + "个数比平均值小");
    }
}

方法重载

  • 在同一个类中,定义了多个同名的方法,这些同名的方法具有相同的功能
  • 每个方法具有不同的参数类型或参数个数,这些同名的方法就构成了重构关系

面向对象 类

类的定义

  • 用来描述一类事物的类,专业叫做:javabean类
  • 在javabean类中是不写main方法的
  • 在以前main方法中编写的类叫做测试类
  • 我们可以在测试类中创建javabean类的对象并赋值调用

格式

public class Test {
    //1.成员变量(代表属性)
    //2.成员方法(代表行为)
}

注意

  • 类名首字符必须大写,需要见名之意,驼峰模式
  • 一个java文件中可以定义多个类,且只能一个类是public修饰的,而且public修饰的类名必须成为代码文件名
  • 实际开发中建议还是一个文件定义一个class类
  • 成员变量的完整定义的格式是:修饰符 数据类型 变量名称 =初始值一般无需指定初始化值,存在默认值

构造方法

  • 构造方法也叫构造器、构造函数
  • 创建对象的时候由虚拟机自动调用,给成员变量进行初始化的
  • 作用:在创建对象的时候给成员变量进行初始化 格式:
public class Text {
    int number;

    private Phone(int number) {
        this.number = number;
    }
}

特点

  • 方法名与类名相同,大小写也要一致
  • 没有返回值类型,连void都没有
  • 没有具体的返回值(不能由return带回结果数据)

idea快速生成空参、有参构造方法、getter、setter

  • 方法一:快捷键 alt+insfn +alt+ins
  • 方法二:插件PTG 1秒生成标准javabean 快捷键 ctrl+shift+,

格斗文字游戏

//people.java类
package text;

import java.util.Random;

public class People {
    //角色姓名
    private String name;
    //角色血量
    private int blod;
    //角色性别
    private char sex;
    //角色长相
    private String appearance;
    //男生长相数组
    String[] manFace = {"风流俊雅", "气宇轩昂", "英俊潇洒", "五官端正", "相貌平平", "喜气洋洋", "大长腿", "高冷", "短发", "长发"};
    //女生长相数组
    String[] womanFace = {"美奂绝伦", "沉鱼落雁", "婷婷玉立", "身材较好", "相貌平平", "相貌简陋", "长发", "短发"};
    //攻击描述
    String[] attackDescArr = {"%s使出一招【普心钉】,转到敌方身后,一掌向%s的灵台穴拍去。",
            "%s使出了一招【游空探爪】,飞起身形自半空中变掌为抓锁向%s。",
            "%s大喝一声,身形下伏,一招【劈雷坠地】,捶向%s双腿",
            "%s运气于掌,一瞬间掌心变得血红,一式【掌心雷】,推向%s。",
            "%s上步抢身,招中套招,一招【劈挂连环】,连环攻向%s",
            "%s阴手翻起阳手跟进,一招【没选拦】,结结实实的捶向%s"
    };
    //受伤描述
    String[] hurtDescArr = {"结果%s退了半步,毫发无损",
            "结果给%s造成一处瘀伤",
            "结果一击命中,%s痛得弯下腰",
            "结果%s痛苦地闷哼了一声,显然受了点内伤",
            "结果%s摇摇晃晃,一跤摔倒在地",
            "结果『轰』的一声,%s口中鲜血狂喷而出",
            "结果%s脸色一下变得惨白,连退了好几步",
            "结果%s一声惨叫,像滩软泥般塌了下去"
    };

    public People(String name, int blod, char sex) {
        this.name = name;
        this.blod = blod;
        setSex(sex);
    }

    public People() {
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
        Random random = new Random();
        if (sex == '男') {
            int r = random.nextInt(manFace.length);
            setAppearance(manFace[r]);
        } else if (sex == '女') {
            int r = random.nextInt(womanFace.length);
            setAppearance(womanFace[r]);
        }
    }

    public String getAppearance() {
        return appearance;
    }

    public void setAppearance(String appearance) {
        this.appearance = appearance;
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     *
     * @return blod
     */
    public int getBlod() {
        return blod;
    }

    /**
     * 设置
     *
     * @param blod
     */
    public void setBlod(int blod) {
        this.blod = blod;
    }

    //角色发起攻击
    public void attack(People people) {
        Random r = new Random();
        //获取随机攻击描述
        String attackDesc = attackDescArr[r.nextInt(attackDescArr.length)];
        System.out.printf(attackDesc, this.name, people.name);
        //获取随机伤害
        int hurt = r.nextInt(10) + 1;
        //计算剩余血量
        int remainBlode = people.getBlod() - hurt;
        people.setBlod(Math.max(remainBlode, 0));
        //获取受伤描述
        String hurtDesc = "";

        int blod = people.getBlod();
        if (blod > 90) hurtDesc = hurtDescArr[0];
        else if (blod > 80) hurtDesc = hurtDescArr[1];
        else if (blod > 70) hurtDesc = hurtDescArr[2];
        else if (blod > 60) hurtDesc = hurtDescArr[3];
        else if (blod > 50) hurtDesc = hurtDescArr[4];
        else if (blod > 40) hurtDesc = hurtDescArr[5];
        else if (blod > 0) hurtDesc = hurtDescArr[6];
        else hurtDesc = hurtDescArr[7];
        System.out.printf(hurtDesc, people.name);
        System.out.print(",造成" + hurt + "点伤害," + people.name + "剩余" + people.getBlod() + "血量");
        System.out.println();
    }

    //展示角色信息
    public void show() {
        System.out.println("姓名:" + getName() + "  血量:" + getBlod() + "  性别:" + getSex() + "  长相:" + getAppearance());
    }
}


//使用
//main.java
import text.People;

public class Main {
    public static void main(String[] args) {
        //文字攻击
        People people1 = new People("James", 100, '男');
        People people2 = new People("Tom", 100, '女');
        people1.show();
        people2.show();
        while (true) {
            people1.attack(people2);
            if (people2.getBlod() <= 0) {
                System.out.println(people1.getName() + "已经死亡,战斗结束");
                break;
            }
            people2.attack(people1);
            if (people1.getBlod() <= 0) {
                System.out.println(people2.getName() + "已经死亡,战斗结束");
                break;
            }
        }
    }
}


java关键字

  • 如class 表示定义类
  • 关键字字母全部小写

class 关键字

用于创建定义一个类 类是java最基本的组成单元

private 关键字

  • 是一个权限修饰符
  • 可以修饰成员、(成员变量、成员方法)
  • 被private修饰的成员变量、成员方法只能在本类中访问
//声明类
public class phone {
    private int price;
    private String brand;
    private String color;

    public void setPrice(int p) {
        this.price = p;
    }

    public int getPrice() {
        return this.price;
    }

    public void call(String name) {
        System.out.println("正在给" + name + "打电话");
    }

    public void sendMessage(String name) {
        System.out.println("正在给" + name + "发短信");
    }
}


//使用类
public class Main {
    public static void main(String[] args) {
        phone myPhone = new phone();
        myPhone.call("James");//正在给James打电话
        myPhone.setPrice(2399);
        System.out.println("手机机价格是" + myPhone.getPrice());//手机机价格是2399
    }
}

lambda表达式

  • lambda表达式最基本的应用就是简化匿名表达式的书写
  • 它是jdk8开始后的一种新语法形式
  • lambda表达式只能简化函数式接口的匿名内部类的写法
  • 函数式接口有且仅有一个抽象方法的接口叫函数式接口,接口上方可以加@FunctionalInterface注解,表示该接口是函数式接口
package api;

import java.util.Arrays;
import java.util.Comparator;

public class LambdaText {
    public static void main(String[] args) {
        Integer[] arr = {1, 4, 2, 6, 4, 3, 8, 9, 7, 5};
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        System.out.println(Arrays.toString(arr));


        //使用Lambda表达式简化匿名内部类
        Integer[] arr2 = {1, 4, 2, 6, 4, 3, 8, 9, 7, 5};
        Arrays.sort(arr2, (o1, o2) -> {
            return o1 - o2;
        });
        System.out.println(Arrays.toString(arr2));
    }

}

使用

public class LambdaText {
    public static void main(String[] args) {
        scText(new Swim() {
            @Override
            public void swiming() {
                System.out.println("我在游泳");
            }
        });
        //使用lambda表达式简化
        scText(() -> System.out.println("我在游泳"));
    }

    //调用方法的时候如果这个方法的形参是一个接口,那么我们就要传递这个接口的实现类对象
    //如果实现类对象只要用到一次,就可以使用Lambda表达式来简化
    public static void scText(Swim swim) {
        swim.swiming();
    }

    //使用匿名内部类的前提该要是一个接口 不能是抽象类
    @FunctionalInterface //该注解表示这是一个函数式接口,只有一个抽象方法
    interface Swim {
        public abstract void swiming();
        //   public abstract void swimings();报错
    }
}

Lambda表达式的省略写法

  • 主要思想:可推导,可省略 Lambda表达式的省略写法
  1. 参数类型可以省略不写
  2. 如果只有一个参数,参数类型可以省略,同时()也可以省略
  3. 如果Lambda表达式的方法体只有一行代码,可以省略大括号和return关键字

练习


class GF {
    String name;
    int age;
    double height;

    public GF(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public class LambdaText {
        public static void main(String[] args) {
            //练习
            //定义第一个存储字符串的数组 字符短的在前面 长的在后面
            String[] arr3 = {"aaaa", "aa", "a", "aaa", "aaaa"};
            Arrays.sort(arr3, (o1, o2) -> o1.length() - o2.length());
            System.out.println(Arrays.toString(arr3));//[a, aa, aaa, aaaa, aaaa]

            //定义数组并存储一些女朋友对象,利用Arrays中的sort方法进行排序
            //要求:属性有姓名。年龄、身高
            //要求2:按照年龄的大小进行排序,年龄一样的按照身高进行排序,身高一样的按照姓名字母进行排序


            GF[] arr4 = {new GF("小红", 18, 1.68), new GF("小明", 19, 1.70), new GF("小花", 18, 1.68)};
            Arrays.sort(arr4, (o1, o2) ->

            {
                if (o1.age != o2.age) return o1.age - o2.age;
                if (o1.height != o2.height) return (int) (o1.height - o2.height);
                //将字符串按照字典的顺序(Ascii码的顺序)进行比较
                return o1.name.compareTo(o2.name);
            });
            System.out.println(Arrays.toString(arr4));
        }
    }
上次更新 2025/10/24 11:25:34