常用类之比较器
一、Java比较器
【说明】
- Java中的对象,正常情况下,只能用 “== 或 != ”进行比较。不能使用 > 或 < 进行比较 ;
- 但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小;
- 如何实现?使用两个接口中的任何一个:Comparable(自然排序) 或 Comparator(定制排序);
二、Comparable接口
自然排序;
【说明】
- 像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式;
- 像String、包装类重写compareTo()方法以后,进行了从小到大的排列;
- 重写compareTo(obj)的规则:
- 如果当前对象this大于形参对象obj,则返回正整数;
- 如果当前对象this小于形参对象obj,则返回负整数;
- 如果当前对象this等于形参对象obj,则返回零;
【String类的代码示例】
@Test
public void test1(){
String[] arr = new String[]{"AA", "BB", "KK","CC", "MM", "GG", "JJ"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
//输出:[AA, BB, CC, GG, JJ, KK, MM]
//Arrays.sort会调用String的compareTo方法,然后根据compareTo方法的返回值进行排序
【自定义类】
对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。在compareTo(obj)方法中指明如何排序;
【自定义类的代码示例】
public class Goods implements Comparable{
private String name;
private double price;
// 构造器、getter、setter、toString():略
//指明商品比较大小的方式:照价格从低到高排序,再照产品名称从高到低排序
@Override
public int compareTo(Object o) {
if(o instanceof Goods){
Goods goods = (Goods)o; //强转为子类方便调用子类属性;
//价格(double类型)比较方式一:
if(this.price > goods.price){
return 1;
}else if(this.price < goods.price){
return -1;
}else{
//调用string的compareTo方法;加个负号令它从大到小排序;
return -this.name.compareTo(goods.name);
}
//价格(double类型)比较方式二:
//return Double.compare(this.price,goods.price);
}
//如果参数o不是Goods的相关类型,抛出异常;
throw new RuntimeException("传入的数据类型不一致!");
}
}
@Test
public void test2(){
Goods[] arr = new Goods[4];
arr[0] = new Goods("lenovoMouse", 34);
arr[1] = new Goods("dellMouse", 43);
arr[2] = new Goods("xiaomiMouse", 12);
arr[3] = new Goods("huaweiMouse", 65);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
//输出:[Goods{name='xiaomiMouse', price=12.0}, Goods{name='lenovoMouse', price=34.0}, Goods{name='dellMouse', price=43.0}, Goods{name='huaweiMouse', price=65.0}]
【说明】
Arrays.sort会调用数组元素对象对应的compareTo方法,然后根据compareTo方法的返回值进行排序;
三、Comparator接口
定制排序;
【说明】
当元素的类型没实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来定制排序;
【使用】
实现Comparator接口的compare(Object o1,Object o2)方法;
比较o1和o2的大小:
- 如果方法返回正整数,则表示o1大于o2;
- 如果返回0,表示相等;
- 返回负整数,表示o1小于o2。
【代码示例】
@Test
public void test4(){
Goods[] arr = new Goods[4];
arr[0] = new Goods("lenovoMouse", 34);
arr[1] = new Goods("dellMouse", 43);
arr[2] = new Goods("xiaomiMouse", 12);
arr[3] = new Goods("huaweiMouse", 65);
/*
指明商品比较大小的方式:按照产品名称从低到高排序,再按照价格从高到底排序;
在Arrays.sort()传入一个comparator实现类对象;这时我们就不用修改原先类中的排序方式;
*/
Arrays.sort(arr, new Comparator<Goods>() { //泛型来规定对象类型;不用泛型则要判断
@Override
public int compare(Goods o1, Goods o2) {
if (o1.getName().equals(o2.getName())){
//Double包装类的静态compare方法,可以比较两个double类型数据
return -Double.compare(o1.getPrice(), o2.getPrice());
}
return o1.getName().compareTo(o2.getName());
}
});
System.out.println(Arrays.toString(arr));
}
四、两种排序方式对比
- Comparable接口的方式是一定的,保证Comparable接口实现类的对象在任何位置都可以比较大小;比如String类等,它里面的规定的排序规则我们是不能改的;
- Comparator接口属于临时性的比较;
其他常用类
一、System类
【说明】
- System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包;
- 由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用;
【成员方法】
- native long currentTimeMillis();
该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数;
- void exit(int status);
该方法的作用是退出程序。其中 status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等;
- void gc();
该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况;
- String getProperty(String key);
该方法的作用是获得系统中属性名为key的属性对应的值。
- 系统中常见的属性名以及属性的作用如下表所示:
二、Math类
java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型;
【常用静态方法】
三、BigInteger类与BigDecimal类
1、BigInteger
Integer整型的最大值不够用怎么办?使用BigIntegar;
【说明】
- java.math包的BigInteger可以表示不可变的任意精度的整数;
- BigInteger提供所有Java的基本整数操作符的对应物,并提供 java.lang.Math的所有相关方法;
- 另外,BigInteger还提供以下运算:模算术、GCD计算、质数测试、素数生成、位操作以及一些其他操作;
【构造器】
BigInteger(String val):根据字符串构建 BigInteger对象;
【常用方法】
【代码示例】
BigInteger bi = new BigInteger("154546546545645645645641515648451564564156456151654");
2、BigDecimal
要求数字精度比较高,用到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 rounding Mode);除
【代码示例】
@Test
public void test() {
BigDecimal bd = new BigDecimal("124356.123");
BigDecimal bd2 = new BigDecimal("123");
//没有处理方式,除不尽就报错;
//System.out.println(bd.divide(bd2));
//处理方式:四舍五入
System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));
//处理方式:小数点后25位四舍五入
System.out.println(bd.divide(bd2, 25, BigDecimal.ROUND_HALF_UP));
}