第九章 Java常用类
9.4 Java比较器:Comparable接口和Comparator接口
9.4.1 Comparable接口的使用
自然排序:java.lang.Comparable
①.Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
②.实现Comparable的类必须实现compareTo(Object obj)方法,两个对象即通过compareTo(Object obj)方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
③.实现Comparable接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需制定比较器。
④.对于类C的每一个e1和e2来说,当且仅当e1.compareTo(e2) == 0 与e1.equals(e2)具有相同的boolean值时,类C的自然排序才叫做与equals一致。建议最好使自然排序与equals一致。
import java.util.Arrays;
//Arrays.sort()方法重写compareTo(Object obj)方法进行排序
public class ComparableTest {
public static void main(String[] args) {
String[] strings = {"aa","dd","ee","cc","zz","gg"};
Arrays.sort(strings);
System.out.println(Arrays.toString(strings));
}
}
9.4.2 实现Comparable接口重写compareTo()方法实现自然排序实例
import java.util.Arrays;
public class Goods implements Comparable {
private String name;
private int age;
public Goods(String name, int age) {
this.name = name;
this.age = age;
}
public Goods() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//指明goods比较大小的方式:按照年龄从低到高排序,再按goods名字从高到低排序
@Override
public int compareTo(Object o) {
if (o instanceof Goods){
Goods goods = (Goods) o;
//方式一
if (this.age>goods.age){
return 1;
}else if (this.age< goods.age){
return -1;
}else {
return this.name.compareTo(goods.name);
}
//方式二
// return Double.compare(this.age,goods.age);
}
//return 0;
throw new RuntimeException("传入的数据类型不一致");
}
}
//重写compareTo方法实现数组的多功能排序
class ComparableTest {
public static void main(String[] args) {
Goods[] goods = new Goods[5];
goods[0] = new Goods("lisi",48);
goods[1] = new Goods("liuer",48);
goods[2] = new Goods("zhangsan",12);
goods[3] = new Goods("wanger",35);
goods[4] = new Goods("liming",21);
Arrays.sort(goods);
System.out.println(Arrays.toString(goods));
}
}
9.4.3 Comparator接口的使用
定制排序:java.util.Comparator
①.当元素的类型没有实现java.lang.Comparable接口而又不方便修改密码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。
②.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示 o1大于o2;如果返回负整数,则表示 o1小于o2;返回0:代表相等。
③.可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。
④.还可以使用 Comparator 来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序
9.4.4 Comparable接口和Comparator接口的使用对比
Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小;Comparator接口属于临时性的比较。
9.4.5 实现Comparator接口重写compare()方法实现定制排序实例
import java.util.Arrays;
import java.util.Comparator;
public class Goods{
private String name;
private int age;
public Goods(String name, int age) {
this.name = name;
this.age = age;
}
public Goods() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//重写compare()方法,比较大小实现数组的多功能排序,Comparator接口即时性排序
class ComparableTest {
public static void main(String[] args) {
Goods[] goods = new Goods[5];
goods[0] = new Goods("fisi", 18);
goods[1] = new Goods("fisi", 24);
goods[2] = new Goods("dhangsan", 12);
goods[3] = new Goods("canger", 35);
goods[4] = new Goods("aiming", 21);
Arrays.sort(goods, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
if (o1.getName().equals(o2.getName())) {
return Double.compare(o1.getAge(), o2.getAge());
} else if (true){
return o1.getName().compareTo(o2.getName());
} else {
throw new RuntimeException("传入的数据类型不一致");
}
}
});
System.out.println(Arrays.toString(goods));
}
}
9.5 System类
9.5.1 System类的介绍
①.System累代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。
②.由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类其内部的成员变量和成员方法都是静态(static)的,所以也可以很方便的进行调用。
③.System类的成员变量:内部包含in,out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
9.5.2 System类的成员方法
①.native long currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间((格林威治时间)1970年1月1日0时0分0秒所差的毫秒数。
②.void exit(int status):该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
③.void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立即回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
④.String getProperty(String key):该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性以及属性的作用如下表所示:
9.5.3 System类的成员方法的使用
//System成员方法的使用
public class SystemText {
public static void main(String[] args) {
//native long currentTimeMillis()方法的使用
System.out.println("当前计算机时间和GMT时间((格林威治时间)1970年1月1日0时0分0秒所差的毫秒数为:"+System.currentTimeMillis()+"毫秒");
//void exit(int status)方法的使用,直接退出不再执行下面的代码
System.exit(0);
//String getProperty(String key)方法的使用
System.out.println("Java运行环境版本:" + System.getProperty("java.version"));
System.out.println("Java安装目录:" + System.getProperty("java.home"));
System.out.println("操作系统的名称:" + System.getProperty("os.name"));
System.out.println("操作系统的版本:" + System.getProperty("os.version"));
System.out.println("用户的账户名称:" + System.getProperty("user.name"));
System.out.println("用户的主目录:" + System.getProperty("user.home"));
System.out.println("用户当前工作目录:" + System.getProperty("user.dir"));
//void gc()方法的使用
System.gc();
/* 输出结果:
* 当前计算机时间和GMT时间((格林威治时间)1970年1月1日0时0分0秒所差的毫秒数为:1637726172051毫秒
* Java运行环境版本:16.0.1
* Java安装目录:D:\Java\jdk-16.0.1
* 操作系统的名称:Windows 10
* 操作系统的版本:10.0
* 用户的账户名称:Administrator
* 用户的主目录:C:\Users\Administrator
* 用户当前工作目录:D:\Java\JavaFoundationUp
*/
}
}
9.6 Math类
9.6.1 Math类的方法与使用
java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。
abs(绝对值),acos,asin,cos,atan,sin,tan(三角函数),sqrt(平方根),pow(double a ,double b) a的b次幂,log(自然对数),exp(e为底指数);
max(double a,double b),min(double a,double b),random()(返回0.0到1.0的随机数),long round(double a )(double型数据a转换为long型,四舍五入)。
//Math相关方法的使用
public class MathText {
public static void main(String[] args) {
int a = -1;
double b = 2.0;
double c = 2.0;
System.out.println("绝对值为:"+Math.abs(a));
System.out.println("三角函数sin:"+Math.sin(b));
System.out.println("平方根:"+Math.sqrt(25));
System.out.println("a的b次幂:"+Math.pow(b ,c));
System.out.println("自然对数:"+Math.log(b));
System.out.println("e为底指数:"+Math.exp(b));
System.out.println("最大值:"+Math.max(a,b));
System.out.println("最小值:"+Math.min(a,c));
System.out.println("返回0.0到1.0的随机数:"+Math.random()*10);
System.out.println("double型数据a转换为long型,四舍五入:"+Math.round(b));
}
}
9.7 BigInteger与BigDecimal
9.7.1 BigInteger类的概述
①.Integer类作为int的包装类,能存储的最大整形值为(2的31次方-1),Long类也是有限的,最大为(2的63次方-1)。如果需要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
②.java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger提供所有Java的基本整数操作符的对应物,并提供java.lang.Math的所有相关方法。另外BigInteger还提供了以下运算:模运算,GCD计算,质数测试,素数生成。位操作以及一些其他操作。
③.构造器:BigInteger(String val):根据字符串构建BigInteger对象
9.7.2 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 a):返回其值为(this的a次幂)的BigInteger
import java.math.BigInteger;
import java.util.Arrays;
public class MathText {
public static void main(String[] args) {
BigInteger bigInteger1 = new BigInteger("-5");
BigInteger bigInteger2 = new BigInteger("-5");
System.out.println("绝对值:" + bigInteger1.abs());
System.out.println("this+val:" + bigInteger1.add(bigInteger2));
System.out.println("this-val:" + bigInteger1.subtract(bigInteger2));
System.out.println("this*val:" + bigInteger1.multiply(bigInteger2));
System.out.println("this/val:" + bigInteger1.divide(bigInteger2));
System.out.println("this%val:" + bigInteger1.remainder(bigInteger2));
BigInteger[] bigIntegers = bigInteger1.divideAndRemainder(bigInteger2);
System.out.println("数组[this/val,this%val]:" + Arrays.toString(bigIntegers));
System.out.println("this的a次幂:" + bigInteger1.pow(2));
/* 输出结果
绝对值:5
this+val:-10
this-val:0
this*val:25
this/val:1
this%val:0
数组[this/val,this%val]:[1, 0]
this的a次幂:25
*/
}
}
9.7.3 BigDecimal类的概述
①.一般的Float类和Double类可以用来做科学计算和工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。
②.BigDecimal类支持不可变的,任意精度的有符号十进制定点数。
③.构造器:public BigDecimal(double val)
public BigDecimal(String val)
9.7.4 BigDecimal类的常用方法
①.public BigDecimal add(BigDecimal augend)
②.public BigDecimal subtract(BigDecimal subtractend)
③.public BigDecimal multiply(BigDecimal multiplicand)
④.public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
import java.math.BigDecimal;
public class MathText {
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal(4.0);
BigDecimal bigDecimal2 = new BigDecimal(4.0);
System.out.println("this+val:" + bigDecimal1.add(bigDecimal2));
System.out.println("this-val:" + bigDecimal1.subtract(bigDecimal2));
System.out.println("this*val:" + bigDecimal1.multiply(bigDecimal2));
System.out.println("this/val:" + bigDecimal1.divide(bigDecimal2));
/* 输出结果
this+val:8
this-val:0
this*val:16
this/val:1
*/
}
}