博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JavaEE - 09常用类3

Posted on 2020-12-07 22:04  Kingdomer  阅读(75)  评论(0编辑  收藏  举报

JavaEE - 09常用类3 

(4)Java比较器

Comparable接口使用:String implements Comparable<String>

    @Test
    public void test1(){
        String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));  //[AA, CC, DD, GG, JJ, KK, MM]
    }

(4.1)自然排序: java.lang.Comparable

  • Comparable接口强行对实现它的每个类的对象进行整体排序。被称为类的自然排序。
  • 实现Comparable的类必须实现compareTo(Object obj)方法,两个对象通过此方法的返回值来比较大小。
    • 如果当前对象this大于形参对象obj,返回正整数;当前对象小于形参对象,返回负整数;等于则返回零。
  • 实现Comparable接口的对象列表和数组可以通过Collections.sort或Arrays.sort进行自然排序。
    • 实现此接口的对象可以用作有序映射的键或有序集合中的元素,无需指定比较器。
  • 对于类C的每一个e1和e2来说,当且仅当e1.compareTo(e2)==0 与 e1.equals(e2)具有相同的boolean值时,类C的自然排序才叫做与equals一致。
    • 建议最好使自然排序与equals一致。
  • String、包装类等实现了Comparable接口,重写了compareTo()方法,进行了从小到大的排序

按照价格从低到高排序: return Double.compare(this.price, goods.price );

public class Goods implements Comparable {
    private String name;
    private double price;

    public Goods(){}
    public Goods(String name, double price) {
        this.name = name;
        this.price = price;
    }
    //指明商品比较大小的方式: 按照价格从低到高排序,再按照产品名称从高到低排序
    @Override
    public int compareTo(Object o){
        if(o instanceof Goods){
            Goods goods = (Goods) o;
            if(this.price > goods.price){
                return 1;
            }else if(this.price < goods.price){
                return -1;
            }else {
//                return 0; 
                return -this.name.compareTo(goods.name);
            }
        }
        throw new RuntimeException("输入的数据类型不一致");
    }
    // 省略其他代码
}

 

    @Test
    public void test2(){
        Goods goods1 = new Goods("Apple",2.9);
        Goods goods2 = new Goods("Banana",3.5);
        Goods goods3 = new Goods("Purple",3.2);
        Goods goods4 = new Goods("Perple",2.9);
        
        Goods[] arr = new Goods[]{goods1,goods2,goods3,goods4};
        //[Goods{name='Apple', price=2.9}, Goods{name='Banana', price=3.5}, Goods{name='Purple', price=3.2}, Goods{name='Perple', price=2.9}]
        System.out.println(Arrays.toString(arr)); 
        Arrays.sort(arr);
        //[Goods{name='Perple', price=2.9}, Goods{name='Apple', price=2.9}, Goods{name='Purple', price=3.2}, Goods{name='Banana', price=3.5}]
        System.out.println(Arrays.toString(arr)); 
    }

(4.2)定制排序: java.util.Comparator

  • 当元素的类型没有实现 java.lang.Comparable接口而又不方便更改代码,或者实现了java.lang.Comparable接口的排序规则不合适当前的操作,
    • 那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。
  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:返回正整数,o1大于o2;负整数,o1小于o2;零,o1等于o2。
  • 可以将Comparator传递给sort方法(Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。
  • 还可以使用Comparator来控制某些数据结构(有序set或有序映射)的顺序,或者为没有自然顺序的对象collection提供排序。

字符串数组按字母从大到小排序

    @Test
    public void test3(){
        String[] arr = new String[]{"AA","BB","AB","GG","JJ","DD"};
        Arrays.sort(arr, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof String && o2 instanceof  String){
                    String s1 = (String) o1;
                    String s2 = (String) o2;
                    return -s1.compareTo(s2);
                }
                throw new RuntimeException("输入的数据类型不一致");
            }
        });
        System.out.println(Arrays.toString(arr)); //[JJ, GG, DD, BB, AB, AA]
    }

按照产品名称从低到高排序,再按照价格从高到低排序 

   @Test
    public void test4(){
        Goods goods1 = new Goods("Apple",2.9);
        Goods goods2 = new Goods("Banana",3.5);
        Goods goods3 = new Goods("Purple",2.2);
        Goods goods4 = new Goods("Purple",2.9);

        Goods[] arr = new Goods[]{goods1,goods2,goods3,goods4};
        // 按照产品名称从低到高排序,再按照价格从高到低排序
        Arrays.sort(arr,new Comparator(){
            @Override
            public int compare(Object o1, Object o2){
                if(o1 instanceof Goods && o2 instanceof Goods){
                    Goods g1 = (Goods) o1;
                    Goods g2 = (Goods) o2;
                    if(g1.getName().equals(g2.getName())){
                        return -Double.compare(g1.getPrice(),g2.getPrice());
                    }else{
                        return g1.getName().compareTo(g2.getName());
                    }
                }
                throw new RuntimeException("输入的数据类型不一致");
            }
        });
        //[Goods{name='Apple', price=2.9}, Goods{name='Banana', price=3.5}, Goods{name='Purple', price=2.9}, Goods{name='Purple', price=2.2}]
        System.out.println(Arrays.toString(arr));
    }

(4.3)说明

  • Java中的对象,正常情况下,只能进行比较: == 或 !=。不能使用 > 或 < 。
  • 如果需要对多个对象进行排序,需要比较对象大小。可以使用两个接口中的任何一个: Comparable 或 Comparator。
  • Comparable接口的方式一旦确定,类的对象在任何位置都可以比较大小。Comparator接口属于临时性比较。

(5)System类

  • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。
  • 由于该类的构造器是private的,所以无法创建该类的对象,无法实例化。其内部的成员变量和成员方法都是static的。
  • 成员变量: 三个:in标准输入流(键盘输入)、out标准输出流(显示器)、err标准错误输出流(显示器)
  • 成员方法
    • native long currentTimeMillis():返回当前计算机时间,与GMT时间1970-01-01 00:00:00所差的毫秒数。
    • void exit(int status):退出程序。0代表正常退出,非零代表异常退出。使用该方法在图形界面编程中实现程序的退出功能等。
    • void gc(): 请求系统进行垃圾回收。是否立刻回收,取决于系统中垃圾回收算法的实现及系统执行时的情况。
    • String getProperty(String key): 获取系统中属性名为key的属性对应的值。
      • java.version / java.home / os.name / os.version / user.name / user.home / user.dir

(6)Math类

java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型。

  • abs:                         绝对值
  • acos,asin,atan,cos,sin,tan:  三角函数
  • sqrt:                        平方根
  • pow(double a, double b):     a的b次幂
  • log:                         自然对数
  • max(double a, double b):
  • min(double a, double b):
  • random():                    返回0.0 到1.0的随机数
  • long round(double a):        double型数据a 转换为long型(四舍五入)
  • toDegress(double angrad):    弧度 -> 角度
  • toRadians(double angras):    角度 -> 弧度

(7)BigDecimal与BigInteger

(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对象
    @Test
    public void test7(){
        BigInteger bi = new BigInteger("12131321111111111111111113211321321321312");
        System.out.println(bi); //12131321111111111111111113211321321321312
    }

(7.2)BigDecimal类

  • 一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数字精度比较高,故用到java.math.BigDecimal类。
  • BigDecimal类支持不可变的、任意精度的有符号十进制定点数。
  • 构造器: public BigDecimal(String val)  /  public BigDecimal(double 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)
    @Test
    public void test5(){
        BigDecimal decimal1 = new BigDecimal("22.22");
        BigDecimal decimal2 = new BigDecimal("11.12");
        System.out.println(decimal1.add(decimal2));       //33.34
        System.out.println(decimal1.subtract(decimal2));  //11.10
        System.out.println(decimal1.multiply(decimal2));  //247.0864
        System.out.println(decimal1.divide(decimal2,2,2)); //2.00
    }

使用Double进行加减乘除计算 

    @Test
    public void test6(){
        Double double1 = new Double("22.22");
        Double double2 = new Double("11.12");
        System.out.println(double1 + double2); //33.339999999999996
        System.out.println(double1 - double2); //11.1
        System.out.println(double1 * double2); //247.08639999999997
        System.out.println(double1 / double2); //1.9982014388489209
    }

BigDecimal divide() 保留小数位数 

    @Test
    public void test7(){
        BigDecimal bd = new BigDecimal("12435.351");
        BigDecimal bd2 = new BigDecimal("11");
        System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));      //1130.486
        System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));  //1130.486454545454545

    }

divide 报错

System.out.println(bd.divide(bd2));
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    at java.math.BigDecimal.divide(BigDecimal.java:1693)
    at Test03.main(Test03.java:49)