【Java】常用类和基础API

文章目录

  • 一、String的特性
  • 二、String的内存结构
    • 2.1 拼接
    • 2.2 new
  • 三、String的常用API-1
    • 3.1 构造器
  • 四、String的常用API-2
    • 4.1 常用方法
    • 4.2 查找
    • 4.3 字符串截取
    • 4.4 和字符/字符数组相关
    • 4.5 开头与结尾
    • 4.6 替换
  • 五、StringBuffer、StringBuilder
    • 5.1 StringBuilder、StringBuffer的API
  • 六、JDK8:新的日期时间API
    • 6.1 本地日期时间:LocalDate、LocalTime、LocalDateTime
    • 6.2 瞬时:Instant
    • 6.3 日期时间格式化:DateTimeFormatter
    • 6.4 其它API
      • 6.4.1 指定时区日期时间:ZondId和ZonedDateTime
      • 6.4.2 持续日期/时间:Period和Duration
      • 6.4.3 Clock:
      • 6.4.4 TemporalAdjuster
  • 七、Java比较器
    • 7.1 自然排序:java.lang.Comparable
    • 7.2 定制排序:java.util.Comparator
  • 八、系统相关类
    • 8.1 java.lang.System类
    • 8.2 java.lang.Runtime类
  • 九、和数学相关的类
    • 9.1 java.lang.Math
    • 9.2 java.math包
    • 9.3 java.util.Random
  • 总结


一、String的特性

  • java.lang.String 类代表字符串。
  • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。
  • 字符串String类型本身是final声明的,意味着我们不能继承String。
  • String对象的字符内容是存储在一个字符数组value[]中的。"abc" 等效于 char[] data={'h','e','l','l','o'}
    1

二、String的内存结构

因为字符串对象设计为不可变,那么所以字符串有常量池来保存很多常量对象。
JDK6中,字符串常量池在方法区。JDK7开始,就移到堆空间,直到目前JDK17版本。

举例内存结构分配:
在这里插入图片描述

2.1 拼接

String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);
// 内存中只有一个"hello"对象被创建,同时被s1和s2共享。

2.2 new

String str1 = “abc”; 与 String str2 = new String(“abc”);的区别?
1
str2 首先指向堆中的一个字符串对象,然后堆中字符串的value数组指向常量池中常量对象的value数组。

  • 字符串常量存储在字符串常量池,目的是共享。
  • 字符串非常量对象存储在堆中。

三、String的常用API-1

3.1 构造器

  • public String() :初始化新创建的 String对象,以使其表示空字符序列。
  • String(String original): 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
  • public String(char[] value) :通过当前参数中的字符数组来构造新的String。
  • public String(char[] value,int offset, int count) :通过字符数组的一部分来构造新的String。
  • public String(byte[] bytes) :通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。
  • public String(byte[] bytes,String charsetName) :通过使用指定的字符集解码当前参数中的字节数组来构造新的String。
//字面量定义方式:字符串常量对象
String str = "hello";//构造器定义方式:无参构造
String str1 = new String();//构造器定义方式:创建"hello"字符串常量的副本
String str2 = new String("hello");//构造器定义方式:通过字符数组构造
char chars[] = {'a', 'b', 'c','d','e'};     
String str3 = new String(chars);
String str4 = new String(chars,0,3);//构造器定义方式:通过字节数组构造
byte bytes[] = {97, 98, 99 };     
String str5 = new String(bytes);
String str6 = new String(bytes,"GBK");

四、String的常用API-2

4.1 常用方法

1boolean isEmpty():字符串是否为空
(2int length():返回字符串的长度
(3String concat(xx):拼接
(4boolean equals(Object obj):比较字符串是否相等,区分大小写
(5boolean equalsIgnoreCase(Object obj):比较字符串是否相等,不区分大小写
(6int compareTo(String other):比较字符串大小,区分大小写,按照Unicode编码值比较大小
(7int compareToIgnoreCase(String other):比较字符串大小,不区分大小写
(8String toLowerCase():将字符串中大写字母转为小写
(9String toUpperCase():将字符串中小写字母转为大写
(10String trim():去掉字符串前后空白符
(11public String intern():结果在常量池中共享
	@Testpublic void test01(){//将用户输入的单词全部转为小写,如果用户没有输入单词,重新输入Scanner input = new Scanner(System.in);String word;while(true){System.out.print("请输入单词:");word = input.nextLine();if(word.trim().length()!=0){word = word.toLowerCase();break;}}System.out.println(word);}@Testpublic void test02(){//随机生成验证码,验证码由0-9,A-Z,a-z的字符组成char[] array = new char[26*2+10];for (int i = 0; i < 10; i++) {array[i] = (char)('0' + i);}for (int i = 10,j=0; i < 10+26; i++,j++) {array[i] = (char)('A' + j);}for (int i = 10+26,j=0; i < array.length; i++,j++) {array[i] = (char)('a' + j);}String code = "";Random rand = new Random();for (int i = 0; i < 4; i++) {code += array[rand.nextInt(array.length)];}System.out.println("验证码:" + code);//将用户输入的单词全部转为小写,如果用户没有输入单词,重新输入Scanner input = new Scanner(System.in);System.out.print("请输入验证码:");String inputCode = input.nextLine();if(!code.equalsIgnoreCase(inputCode)){System.out.println("验证码输入不正确");}}

4.2 查找

11boolean contains(xx):是否包含xx
(12int indexOf(xx):从前往后找当前字符串中xx,即如果有返回第一次出现的下标,要是没有返回-113int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
(14int lastIndexOf(xx):从后往前找当前字符串中xx,即如果有返回最后一次出现的下标,要是没有返回-115int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。

4.3 字符串截取

16String substring(int beginIndex) :返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。 
(17String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
@Test
public void test01(){String str = "helloworldjavaatguigu";String sub1 = str.substring(5);String sub2 = str.substring(5,10);System.out.println(sub1);System.out.println(sub2);
}@Test
public void test02(){String fileName = "快速学习Java的秘诀.dat";//截取文件名System.out.println("文件名:" + fileName.substring(0,fileName.lastIndexOf(".")));//截取后缀名System.out.println("后缀名:" + fileName.substring(fileName.lastIndexOf(".")));
}

4.4 和字符/字符数组相关

18char charAt(index):返回[index]位置的字符
(19char[] toCharArray(): 将此字符串转换为一个新的字符数组返回
(20static String valueOf(char[] data)  :返回指定数组中表示该字符序列的 String21static String valueOf(char[] data, int offset, int count) : 返回指定数组中表示该字符序列的 String22static String copyValueOf(char[] data): 返回指定数组中表示该字符序列的 String23static String copyValueOf(char[] data, int offset, int count):返回指定数组中表示该字符序列的 String
	@Testpublic void test01(){//将字符串中的字符按照大小顺序排列String str = "helloworldjavaatguigu";char[] array = str.toCharArray();Arrays.sort(array);str = new String(array);System.out.println(str);}@Testpublic void test02(){//将首字母转为大写String str = "jack";str = Character.toUpperCase(str.charAt(0))+str.substring(1);System.out.println(str);}@Testpublic void test03(){char[] data = {'h','e','l','l','o','j','a','v','a'};String s1 = String.copyValueOf(data);String s2 = String.copyValueOf(data,0,5);int num = 123456;String s3 = String.valueOf(num);System.out.println(s1);System.out.println(s2);System.out.println(s3);}

4.5 开头与结尾

24boolean startsWith(xx):测试此字符串是否以指定的前缀开始 
(25boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
(26boolean endsWith(xx):测试此字符串是否以指定的后缀结束 

4.6 替换

27String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 不支持正则。
(28String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 
(29String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 
(30String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 
@Test
public void test1(){String str1 = "hello244world.java;887";//把其中的非字母去掉str1 = str1.replaceAll("[^a-zA-Z]", "");System.out.println(str1);String str2 = "12hello34world5java7891mysql456";//把字符串中的数字替换成,,如果结果中开头和结尾有,的话去掉String string = str2.replaceAll("\\d+", ",").replaceAll("^,|,$", "");System.out.println(string);}

五、StringBuffer、StringBuilder

区分String、StringBuffer、StringBuilder

  • String:不可变的字符序列; 底层使用char[]数组存储(JDK8.0中)
  • StringBuffer:可变的字符序列;线程安全(方法有synchronized修饰),效率低;底层使用char[]数组存储 (JDK8.0中)
  • StringBuilder:可变的字符序列; jdk1.5引入,线程不安全的,效率高;底层使用char[]数组存储(JDK8.0中)

5.1 StringBuilder、StringBuffer的API

1StringBuffer append(xx):提供了很多的append()方法,用于进行字符串追加的方式拼接
(2StringBuffer delete(int start, int end):删除[start,end)之间字符
(3StringBuffer deleteCharAt(int index):删除[index]位置字符
(4StringBuffer replace(int start, int end, String str):替换[start,end)范围的字符序列为str
(5void setCharAt(int index, char c):替换[index]位置字符
(6char charAt(int index):查找指定index位置上的字符
(7StringBuffer insert(int index, xx):在[index]位置插入xx
(8int length():返回存储的字符数据的长度
(9StringBuffer reverse():反转
1int indexOf(String str):在当前字符序列中查询str的第一次出现下标
(2int indexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的第一次出现下标
(3int lastIndexOf(String str):在当前字符序列中查询str的最后一次出现下标
(4int lastIndexOf(String str, int fromIndex):在当前字符序列[fromIndex,最后]中查询str的最后一次出现下标
(5String substring(int start):截取当前字符序列[start,最后]6String substring(int start, int end):截取当前字符序列[start,end)7String toString():返回此序列中数据的字符串表示形式
(8void setLength(int newLength) :设置当前字符序列长度为newLength

六、JDK8:新的日期时间API

新的日期时间API包含:

  • java.time – 包含值对象的基础包
  • java.time.chrono – 提供对不同的日历系统的访问。
  • java.time.format – 格式化和解析时间和日期
  • java.time.temporal – 包括底层框架和扩展特性
  • java.time.zone – 包含时区支持的类

说明:新的 java.time 中包含了所有关于时钟(Clock),本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。

6.1 本地日期时间:LocalDate、LocalTime、LocalDateTime

方法描述
now() / now(ZoneId zone)静态方法,根据当前时间创建对象/指定时区的对象
of(xx,xx,xx,xx,xx,xxx)静态方法,根据指定日期/时间创建对象
getDayOfMonth()/getDayOfYear()获得月份天数(1-31) /获得年份天数(1-366)
getDayOfWeek()获得星期几(返回一个 DayOfWeek 枚举值)
getMonth()获得月份, 返回一个 Month 枚举值
getMonthValue() / getYear()获得月份(1-12) /获得年份
getHours()/getMinute()/getSecond()获得当前对象对应的小时、分钟、秒
withDayOfMonth()/withDayOfYear()/withMonth()/withYear()将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象
with(TemporalAdjuster t)将当前日期时间设置为校对器指定的日期时间
plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()向当前对象添加几天、几周、几个月、几年、几小时
minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()从当前对象减去几月、几周、几天、几年、几小时
plus(TemporalAmount t)/minus(TemporalAmount t)添加或减少一个 Duration 或 Period
isBefore()/isAfter()比较两个 LocalDate
isLeapYear()判断是否是闰年(在LocalDate类中声明)
format(DateTimeFormatter t)格式化本地日期、时间,返回一个字符串
parse(Charsequence text)将指定格式的字符串解析为日期、时间

6.2 瞬时:Instant

  • Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
    • 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
  • java.time.Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。
方法描述
now()静态方法,返回默认UTC时区的Instant类的对象
ofEpochMilli(long epochMilli)静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象
atOffset(ZoneOffset offset)结合即时的偏移来创建一个 OffsetDateTime
toEpochMilli()返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳

中国大陆、中国香港、中国澳门、中国台湾、蒙古国、新加坡、马来西亚、菲律宾、西澳大利亚州的时间与UTC的时差均为+8,也就是UTC+8。
instant.atOffset(ZoneOffset.ofHours(8));

6.3 日期时间格式化:DateTimeFormatter

自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

ofPattern(String pattern)静态方法,返回一个指定字符串格式的DateTimeFormatter
format(TemporalAccessor t)格式化一个日期、时间,返回字符串
parse(CharSequence text)将指定格式的字符序列解析为一个日期、时间
    @Testpublic void test3(){//自定义的方式DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");//格式化String strDateTime = dateTimeFormatter.format(LocalDateTime.now());System.out.println(strDateTime); //2022/12/04 21:05:42//解析TemporalAccessor accessor = dateTimeFormatter.parse("2022/12/04 21:05:42");LocalDateTime localDateTime = LocalDateTime.from(accessor);System.out.println(localDateTime); //2022-12-04T21:05:42}

6.4 其它API

6.4.1 指定时区日期时间:ZondId和ZonedDateTime

  • ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris

  • ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。

    • 其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等
  • 常见时区ID:Asia/Shanghai UTC America/New_York

  • 可以通过ZondId获取所有可用的时区ID:

    @Testpublic void test01() {//需要知道一些时区的id//Set<String>是一个集合,容器Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();//快捷模板iterfor (String availableZoneId : availableZoneIds) {System.out.println(availableZoneId);}}@Testpublic void test02(){ZonedDateTime t1 = ZonedDateTime.now();System.out.println(t1);ZonedDateTime t2 = ZonedDateTime.now(ZoneId.of("America/New_York"));System.out.println(t2);}

6.4.2 持续日期/时间:Period和Duration

  • 持续时间:Duration,用于计算两个“时间”间隔
  • 日期间隔:Period,用于计算两个“日期”间隔
public class TestPeriodDuration {@Testpublic void test01(){LocalDate t1 = LocalDate.now();LocalDate t2 = LocalDate.of(2018, 12, 31);Period between = Period.between(t1, t2);System.out.println(between);System.out.println("相差的年数:"+between.getYears());System.out.println("相差的月数:"+between.getMonths());System.out.println("相差的天数:"+between.getDays());System.out.println("相差的总数:"+between.toTotalMonths());}@Testpublic void test02(){LocalDateTime t1 = LocalDateTime.now();LocalDateTime t2 = LocalDateTime.of(2017, 8, 29, 0, 0, 0, 0);Duration between = Duration.between(t1, t2);System.out.println(between);System.out.println("相差的总天数:"+between.toDays());System.out.println("相差的总小时数:"+between.toHours());System.out.println("相差的总分钟数:"+between.toMinutes());System.out.println("相差的总秒数:"+between.getSeconds());System.out.println("相差的总毫秒数:"+between.toMillis());System.out.println("相差的总纳秒数:"+between.toNanos());System.out.println("不够一秒的纳秒数:"+between.getNano());}@Testpublic void test03(){//Duration:用于计算两个“时间”间隔,以秒和纳秒为基准LocalTime localTime = LocalTime.now();LocalTime localTime1 = LocalTime.of(15, 23, 32);//between():静态方法,返回Duration对象,表示两个时间的间隔Duration duration = Duration.between(localTime1, localTime);System.out.println(duration);System.out.println(duration.getSeconds());System.out.println(duration.getNano());LocalDateTime localDateTime = LocalDateTime.of(2016, 6, 12, 15, 23, 32);LocalDateTime localDateTime1 = LocalDateTime.of(2017, 6, 12, 15, 23, 32);Duration duration1 = Duration.between(localDateTime1, localDateTime);System.out.println(duration1.toDays());}@Testpublic void test4(){//Period:用于计算两个“日期”间隔,以年、月、日衡量LocalDate localDate = LocalDate.now();LocalDate localDate1 = LocalDate.of(2028, 3, 18);Period period = Period.between(localDate, localDate1);System.out.println(period);System.out.println(period.getYears());System.out.println(period.getMonths());System.out.println(period.getDays());Period period1 = period.withYears(2);System.out.println(period1);}
}

6.4.3 Clock:

使用时区提供对当前即时、日期和时间的访问的时钟。

6.4.4 TemporalAdjuster

TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。
TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。

@Test
public void test1(){// TemporalAdjuster:时间校正器// 获取当前日期的下一个周日是哪天?TemporalAdjuster temporalAdjuster = TemporalAdjusters.next(DayOfWeek.SUNDAY);LocalDateTime localDateTime = LocalDateTime.now().with(temporalAdjuster);System.out.println(localDateTime);// 获取下一个工作日是哪天?LocalDate localDate = LocalDate.now().with(new TemporalAdjuster() {@Overridepublic Temporal adjustInto(Temporal temporal) {LocalDate date = (LocalDate) temporal;if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {return date.plusDays(3);} else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {return date.plusDays(2);} else {return date.plusDays(1);}}});System.out.println("下一个工作日是:" + localDate);}

七、Java比较器

引用类型排序

Java实现对象排序的方式有两种:

  • 自然排序:java.lang.Comparable
  • 定制排序:java.util.Comparator

7.1 自然排序:java.lang.Comparable

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
package java.lang;public interface Comparable{int compareTo(Object obj);
}
  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。

  • 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。建议(虽然不是必需的)最好使自然排序与 equals 一致

  • Comparable 的典型实现:(默认都是从小到大排列的)

    • String:按照字符串中字符的Unicode值进行比较
    • Character:按照字符的Unicode值来进行比较
    • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
    • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
    • Date、Time等:后面的日期时间比前面的日期时间大

举例:

public class Student implements Comparable {private int id;private String name;private int score;private int age;public Student(int id, String name, int score, int age) {this.id = id;this.name = name;this.score = score;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", score=" + score +", age=" + age +'}';}@Overridepublic int compareTo(Object o) {//这些需要强制,将o对象向下转型为Student类型的变量,才能调用Student类中的属性//默认按照学号比较大小Student stu = (Student) o;return this.id - stu.id;}
}

测试:

public class TestStudent {public static void main(String[] args) {Student[] arr = new Student[5];arr[0] = new Student(3,"张三",90,23);arr[1] = new Student(1,"熊大",100,22);arr[2] = new Student(5,"王五",75,25);arr[3] = new Student(4,"李四",85,24);arr[4] = new Student(2,"熊二",85,18);//单独比较两个对象System.out.println(arr[0].compareTo(arr[1]));System.out.println(arr[1].compareTo(arr[2]));System.out.println(arr[2].compareTo(arr[2]));System.out.println("所有学生:");for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}System.out.println("按照学号排序:");for (int i = 1; i < arr.length; i++) {for (int j = 0; j < arr.length-i; j++) {if(arr[j].compareTo(arr[j+1])>0){Student temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}

在举例:

class Goods implements Comparable {private String name;private double price;//按照价格,比较商品的大小@Overridepublic int compareTo(Object o) {if(o instanceof Goods) {Goods other = (Goods) o;if (this.price > other.price) {return 1;} else if (this.price < other.price) {return -1;}return 0;}throw new RuntimeException("输入的数据类型不一致");}//构造器、getter、setter、toString()方法略
}

再测试:

public class ComparableTest{public static void main(String[] args) {Goods[] all = new Goods[4];all[0] = new Goods("《红楼梦》", 100);all[1] = new Goods("《西游记》", 80);all[2] = new Goods("《三国演义》", 140);all[3] = new Goods("《水浒传》", 120);Arrays.sort(all);System.out.println(Arrays.toString(all));}
}

7.2 定制排序:java.util.Comparator

  • 思考
    • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
    • 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?
  • JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。
    • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
    • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
package java.util;public interface Comparator{int compare(Object o1,Object o2);
}

举例:

import java.util.Comparator;
//定义定制比较器类
public class StudentScoreComparator implements Comparator { @Overridepublic int compare(Object o1, Object o2) {Student s1 = (Student) o1;Student s2 = (Student) o2;int result = s1.getScore() - s2.getScore();return result != 0 ? result : s1.getId() - s2.getId();}
}

测试:

public class TestStudent {public static void main(String[] args) {Student[] arr = new Student[5];arr[0] = new Student(3, "张三", 90, 23);arr[1] = new Student(1, "熊大", 100, 22);arr[2] = new Student(5, "王五", 75, 25);arr[3] = new Student(4, "李四", 85, 24);arr[4] = new Student(2, "熊二", 85, 18);System.out.println("所有学生:");for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}System.out.println("按照成绩排序");StudentScoreComparator sc = new StudentScoreComparator();for (int i = 1; i < arr.length; i++) {for (int j = 0; j < arr.length - i; j++) {if (sc.compare(arr[j], arr[j + 1]) > 0) {Student temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}

八、系统相关类

8.1 java.lang.System类

  • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包

  • 由于该类的构造器是private的,所以无法创建该类的对象。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用。

  • 成员变量 Scanner scan = new Scanner(System.in);

    • System类内部包含inouterr三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
  • 成员方法

    • native long currentTimeMillis()
      该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。

    • void exit(int status)
      该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。

    • void gc()
      该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。

    • String getProperty(String key)
      该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:
      1

static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。常用于数组的插入和删除

8.2 java.lang.Runtime类

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。

public static Runtime getRuntime(): 返回与当前 Java 应用程序相关的运行时对象。应用程序不能创建自己的 Runtime 类实例。

public long totalMemory():返回 Java 虚拟机中初始化时的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。默认为物理电脑内存的1/64。

public long maxMemory():返回 Java 虚拟机中最大程度能使用的内存总量。默认为物理电脑内存的1/4。

public long freeMemory():回 Java 虚拟机中的空闲内存量。调用 gc 方法可能导致 freeMemory 返回值的增加。

public class TestRuntime {public static void main(String[] args) {Runtime runtime = Runtime.getRuntime();long initialMemory = runtime.totalMemory(); //获取虚拟机初始化时堆内存总量long maxMemory = runtime.maxMemory(); //获取虚拟机最大堆内存总量String str = "";//模拟占用内存for (int i = 0; i < 10000; i++) {str += i;}long freeMemory = runtime.freeMemory(); //获取空闲堆内存总量System.out.println("总内存:" + initialMemory / 1024 / 1024 * 64 + "MB");System.out.println("总内存:" + maxMemory / 1024 / 1024 * 4 + "MB");System.out.println("空闲内存:" + freeMemory / 1024 / 1024 + "MB") ;System.out.println("已用内存:" + (initialMemory-freeMemory) / 1024 / 1024 + "MB");}
}

九、和数学相关的类

9.1 java.lang.Math

java.lang.Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。类似这样的工具类,其所有方法均为静态方法,并且不会创建对象,调用起来非常简单。

public static double abs(double a) :返回 double 值的绝对值。

double d1 = Math.abs(-5); //d1的值为5
double d2 = Math.abs(5); //d2的值为5

public static double ceil(double a) :返回大于等于参数的最小的整数。

double d1 = Math.ceil(3.3); //d1的值为 4.0
double d2 = Math.ceil(-3.3); //d2的值为 -3.0
double d3 = Math.ceil(5.1); //d3的值为 6.0

floor(double a) :返回小于等于参数最大的整数。

double d1 = Math.floor(3.3); //d1的值为3.0
double d2 = Math.floor(-3.3); //d2的值为-4.0
double d3 = Math.floor(5.1); //d3的值为 5.0

public static long round(double a) :返回最接近参数的 long。(相当于四舍五入方法)

long d1 = Math.round(5.5); //d1的值为6
long d2 = Math.round(5.4); //d2的值为5
long d3 = Math.round(-3.3); //d3的值为-3
long d4 = Math.round(-3.8); //d4的值为-4
  • public static double pow(double a,double b):返回a的b幂次方法
  • public static double sqrt(double a):返回a的平方根
  • public static double random():返回[0,1)的随机值
  • public static final double PI:返回圆周率
  • public static double max(double x, double y):返回x,y中的最大值
  • public static double min(double x, double y):返回x,y中的最小值
  • 其它:acos,asin,atan,cos,sin,tan 三角函数
double result = Math.pow(2,31);
double sqrt = Math.sqrt(256);
double rand = Math.random();
double pi = Math.PI;

9.2 java.math包

  1. BigInteger
  • Integer类作为int的包装类,能存储的最大整型值为231-1,Long类也是有限的,最大为263-1。如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。

  • java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。

  • 构造器

    • BigInteger(String val):根据字符串构建BigInteger对象
  • 方法

    • public BigInteger abs():返回此 BigInteger 的绝对值的 BigInteger。
    • BigInteger add(BigInteger val) :返回其值为 (this + val) 的 BigInteger
    • BigInteger subtract(BigInteger val) :返回其值为 (this - val) 的 BigInteger
    • BigInteger multiply(BigInteger val) :返回其值为 (this * val) 的 BigInteger
    • BigInteger divide(BigInteger val) :返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。
    • BigInteger remainder(BigInteger val) :返回其值为 (this % val) 的 BigInteger。
    • BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。
    • BigInteger pow(int exponent) :返回其值为 (this^exponent) 的 BigInteger。
@Test
public void test01(){//long bigNum = 123456789123456789123456789L;BigInteger b1 = new BigInteger("12345678912345678912345678");BigInteger b2 = new BigInteger("78923456789123456789123456789");//System.out.println("和:" + (b1+b2));//错误的,无法直接使用+进行求和System.out.println("和:" + b1.add(b2));System.out.println("减:" + b1.subtract(b2));System.out.println("乘:" + b1.multiply(b2));System.out.println("除:" + b2.divide(b1));System.out.println("余:" + b2.remainder(b1));
}
  1. BigDecimal
  • 一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。

  • BigDecimal类支持不可变的、任意精度的有符号十进制定点数。

  • 构造器

    • public BigDecimal(double val)
    • public BigDecimal(String val) --> 推荐
  • 常用方法

    • public BigDecimal add(BigDecimal augend)
    • public BigDecimal subtract(BigDecimal subtrahend)
    • public BigDecimal multiply(BigDecimal multiplicand)
    • public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode):divisor是除数,scale指明保留几位小数,roundingMode指明舍入模式(ROUND_UP :向上加1、ROUND_DOWN :直接舍去、ROUND_HALF_UP:四舍五入)
@Test
public void test03(){BigInteger bi = new BigInteger("12433241123");BigDecimal bd = new BigDecimal("12435.351");BigDecimal bd2 = new BigDecimal("11");System.out.println(bi);// System.out.println(bd.divide(bd2));System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));
}

9.3 java.util.Random

用于产生随机数

  • boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 boolean 值。

  • void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。

  • double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 double 值。

  • float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 float 值。

  • double nextGaussian():返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的 double 值,其平均值是 0.0,标准差是 1.0。

  • int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。

  • int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。

  • long nextLong():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。

@Test
public void test04(){Random r = new Random();System.out.println("随机整数:" + r.nextInt());System.out.println("随机小数:" + r.nextDouble());System.out.println("随机布尔值:" + r.nextBoolean());
}

总结

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

湖南麒麟SSH服务漏洞

针对湖南麒麟操作系统进行漏洞检测时&#xff0c;会报SSH漏洞风险提醒&#xff0c;具体如下&#xff1a; 针对这些漏洞&#xff0c;可以关闭SSH服务&#xff08;前提是应用已经部署完毕不再需要通过SSH远程访问传输文件的情况下&#xff0c;此时可以通过VNC远程登录方法&#x…

简单的网页制作

1网页编写格式 <!DOCTYPE html> <html><head><meta charset"utf-8"> <title>中文测试。。。。</title></head><body>这里是测试body测试内容。。。</body> </html>2标签 在body内<h1></h1&…

3D Occupancy 预测冠军方案:FB-OCC

文章结尾有视频和连接 背景知识 Occupancy 更像是一个语义分割任务&#xff0c;但是它是 3D 空间的语义分割它的我们对 Occupancy 分自己的期望是它能够具有通用的这种目标建模的能力&#xff0c;才能够不是不受制于这种目标框这种几何的矩形的这种约束而能够建模任意形状的这…

图像去噪--(1)

系列文章目录 文章目录 系列文章目录前言一、图像噪声1.1 噪声定义1.2 基本特征 二、按照噪声概率分布分类1.高斯噪声2.泊松噪声 三、去噪算法3.1 线性滤波3.1.1 高斯滤波3.1.2 均值滤波 3.2 非线性滤波3.2.1 中值滤波3.2.2 双边滤波 四、深度学习总结 前言 一、图像噪声 1.1 …

加密算法详解

加密学的发展和应用 计算机加密学的发展历程可以大致分为以下几个阶段&#xff1a; 古典密码学时期&#xff08;古代至20世纪初&#xff09;&#xff1a; 在古代&#xff0c;人们就已经开始使用简单的加密技术来保护通信内容&#xff0c;例如凯撒密码、维吉尼亚密码等。到了近…

2024年【天津市安全员C证】新版试题及天津市安全员C证模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员C证新版试题考前必练&#xff01;安全生产模拟考试一点通每个月更新天津市安全员C证模拟考试题题目及答案&#xff01;多做几遍&#xff0c;其实通过天津市安全员C证模拟考试题库很简单。 1、【多选题】《…

Linux安装使用one-api 格式访问所有的大模型

One API ✨ 通过标准的 OpenAI API 格式访问所有的大模型&#xff0c;开箱即用 ✨ [!NOTE] 本项目为开源项目&#xff0c;使用者必须在遵循 OpenAI 的使用条款以及法律法规的情况下使用&#xff0c;不得用于非法用途。 根据《生成式人工智能服务管理暂行办法》的要求&#xff…

主干网络篇 | YOLOv8更换主干网络之ShuffleNetV2(包括完整代码+添加步骤+网络结构图)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。ShuffleNetV2是一种轻量级的神经网络架构&#xff0c;用于图像分类和目标检测任务。它是ShuffleNet的改进版本&#xff0c;旨在提高模型的性能和效率。ShuffleNetV2相比于之前的版本&#xff0c;在保持模型轻量化的同时&am…

inux(CentOS)/Windows-C++ 云备份项目(项目文件操作工具类设计,完成项目基本文件操作-读写-压缩-目录操作)

文章目录 1. 项目文件操作工具类设计 1. 项目文件操作工具类设计 根据前面的分析&#xff0c;这个文件类的基本属性如下&#xff1a; 文件大小信息文件最后修改时间文件最后一次访问时间&#xff0c;方便文件的热点管理文件名称&#xff0c;需要从http 请求行上的uri中获取基…

【智能算法】保姆级教程-如何使用CEC测试集,以及如何定义自己的优化问题

目录 1.准备工作2.使用CEC2005测试集3.自定义优化问题-无约束问题4.自定义优化问题-有约束问题5.代码实现 1.准备工作 一个CEC2005测试集 一个测试智能算法&#xff0c;比如麻雀搜索算法SSA 2.使用CEC2005测试集 以CEC2005测试集函数F7为例&#xff1a; 3.自定义优化问题…

请问腾讯云2核4G服务器最大能支持多少人访问?

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

JavaScript单元代码(1)

1.简单的JavaScript代码 <!doctype html> <html><head><meta charset"utf-8"><title>第一个简单的JavaScript程序</title></head><body><div style"font-size:18px;"><script type"text/j…