【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://xiahunao.cn/news/2869722.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【RS422】基于未来科技FT4232HL芯片的多波特率串口通信收发实现

功能简介 串行通信接口常常用于在计算机和低速外部设备之间传输数据。串口通信存在多种标准&#xff0c;以RS422为例&#xff0c;它将数据分成多个位&#xff0c;采用异步通信方式进行传输。   本文基于Xilinx VCU128 FPGA开发板&#xff0c;对RS422串口通信进行学习。   根…

sqlite 常见命令 表结构

在 SQLite 中&#xff0c;将表结构保存为 SQL 具有一定的便捷性和重要性&#xff0c;原因如下 便捷性&#xff1a; 备份和恢复&#xff1a;将表结构保存为 SQL 可以方便地进行备份。如果需要还原或迁移数据库&#xff0c;只需执行保存的 SQL 脚本&#xff0c;就可以重新创建表…

如何在“Microsoft Visual Studio”中使用OpenCV编译应用程序

返回目录&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 前一篇&#xff1a;OpenCV4.9.0在windows系统下的安装 后一篇&#xff1a; 警告&#xff1a; 本教程可以包含过时的信息。 我在这里描述的所有内容都将适用于 OpenCV 的C\C接口。我首先假…

力扣热题100_矩阵_240_搜索二维矩阵 II

文章目录 题目链接解题思路解题代码 题目链接 240. 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xf…

专升本 C语言笔记-07 逗号运算符

1.逗号表达式的用法 就是用逗号隔开的多个表达式。逗号表达式&#xff0c;从左向右依次执行。 2.逗号表达式的特性 2.1.当没有括号时&#xff0c;第一个表达式为整个表达式的值。 代码 int x 3,y 5,a 0; a x,y; printf("a %d",a); 说明:因为逗号优先级最低,会…

PyTorch学习笔记之激活函数篇(一)

文章目录 1、Sigmoid函数1.1 公式1.2 对应图像1.2 生成图像代码1.4 优点与不足1.5 torch.sigmoid()函数 1、Sigmoid函数 1.1 公式 Sigmoid函数的公式&#xff1a; f ( x ) 1 1 e − x f(x) \frac{1}{1e^{-x}} f(x)1e−x1​ Sigmoid函数的导函数&#xff1a; f ′ ( x ) e …

灯塔:CSS笔记(4)

伪类选择器&#xff1a; 1.作用与优势&#xff1a; 1.作用&#xff1a;根据元素在HTML中的结构关系查找元素 2.优势&#xff1a;减少对于HTML中类的依赖&#xff0c;有利于保持代码的整洁 3.场景&#xff1a;常用于查找某父级选择器中的子元素 2.选择器 选择器说明E:first-c…

软考80-上午题-【面向对象技术3-设计模式】-结构型设计模式03

一、外观模式 1-1、意图 为子系统中的一组接口提供一个一致的界面。 Facade 模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用。 1-2、结构 Facade 知道哪些子系统类负责处理请求&#xff1a;将客户的请求代理给适当的子系统对象。Subsvstem classes …

SpingBoot集成Rabbitmq及Docker部署

文章目录 介绍RabbitMQ的特点Rabbitmq术语消息发布接收流程 Docker部署管理界面说明Overview: 这个页面显示了RabbitMQ服务器的一般信息&#xff0c;例如集群节点的名字、状态、运行时间等。Connections: 在这里&#xff0c;可以查看、管理和关闭当前所有的TCP连接。Channels: …

【ollama】(7):使用Nvidia Jetson Nano设备,成功运行ollama,运行qwen:0.5b-chat,速度还可以,可以做创新项目了

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1Pj421o7W5/ 【ollama】&#xff08;7&#xff09;&#xff1a;使用Nvidia Jetson Nano设备&#xff0c;成功运行ollama&#xff0c;运行qwen:0.5b-chat&#xff0c;速度还可以&#xff0c;可以做创新项目了 2&#x…

源码编译部署LAMP

编译部署LAMP 配置apache [rootzyq ~]#: wget https://downloads.apache.org/apr/apr-1.7.4.tar.gz --2023-12-11 14:35:57-- https://downloads.apache.org/apr/apr-1.7.4.tar.gz Resolving downloads.apache.org (downloads.apache.org)... 88.99.95.219, 135.181.214.104…

MySQL实现事务隔离的秘诀之锁

在MySQL中&#xff0c;有多种锁类型&#xff0c;我们先了解三种概念的锁&#xff0c;以便对接下来的内容有更好理解。 表级锁&#xff08;Table Lock&#xff09;&#xff1a;对整个表加锁&#xff0c;其他事务无法修改或读取该表的数据&#xff0c;但可以对其他表进行操作。页…

【研发管理】产品经理-基础认知

导读&#xff1a;产品经理&#xff08;Product Manager&#xff09;是一个负责产品的全周期管理的职位&#xff0c;他们不仅参与产品的设计、开发、推广和销售&#xff0c;还涉及到产品的市场调研、用户需求分析、竞争分析、产品规划、产品测试以及后续的产品迭代等多个环节。产…

C语言-strtok(切片的使用)

strtok&#xff08;切片的使用&#xff09; 使用规则 使用的基本情况 strcpy 第二次调用的时候传的是空指针 所以打印出来的是 每一次调用函数都会把当前函数的地址记住 所以二次调用的时候 传的是null 连起始位置都不传了 只是传null 但是需要知道的是 当知道三段 你调用第…

MySQL语法分类 DDL(1)

DDL&#xff08;1&#xff09;(操作数据库、表) 数据库操作(CRUD) C(Create):创建 //指定字符集创建 create database db_1 character set utf8;//避免重复创建数据库报错可以用一下命令 create database if not exists db_1 character set utf8;R(Retrieve):查询 //查询所…

由浅到深认识C语言(6):变量的存储类型

该文章Github地址&#xff1a;https://github.com/AntonyCheng/c-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.csdn…

flowable-ui部署

版本 java: java8+tomcat: apache-tomcat-9.0.87flowable: flowable-6.8.1mysql驱动: mysql-connector-java-8.0.30.jar 注意:版本一定要对,否则启动报错执行数据库脚本 创建数据库flowable执行脚本,脚本位于解压flowable-6.8.1.zip后的flowable-6.8.1/database/create/all/…

网络编程套接字——实现简单的UDP网络程序

目录 1、预备知识 1.1、认识端口号 1.2、端口号 vs 进程pid 1.3、认识TCP协议 1.4、认识UDP协议 1.5、网络字节序 2、socket编程接口 2.1、socket常见API 2.2、sockaddr结构 3、实现一个简易的UDP服务器和客户端通信 log.hpp UdpServer.hpp UdpClient.cc Main.cc…

Ubuntu 20.04 系统如何优雅地安装NCL?

一、什么是NCL&#xff1f; NCAR Command Language&#xff08;NCL&#xff09;是由美国大气研究中心&#xff08;NCAR&#xff09;推出的一款用于科学数据计算和可视化的免费软件。 它有着非常强大的文件输入和输出功能&#xff0c;可读写netCDF-3、netCDF-4 classic、HDF4、b…

【全开源】JAVA匿名情侣假装情侣系统源码支持微信小程序+微信公众号+H5

一、功能介绍 匹配情侣、聊天功能、匹配记录 会员功能、我的团队、合伙代理 修改个人资料 我们技术使用JAVA后台服务 前后端分离 springbootmybatisplusmysql 用户端 uniapp&#xff08;vue语法&#xff09;管理后台 vueelementUi 适配小程序H5公众号&#xff0c;一套源码…