Java基础知识疑难点总结

343 阅读3分钟

1. 基础

1.1. 正确使用equals方法

 String str = null;
 str.equals("hjw") // 空指针异常

推荐使用的方法:将需要判断的字符串放到第二个条件

 String userName = null;
 "hjw".equals(userName) // false

更加推荐使用Objects.equals(Object o1, Object o2)

 String str = null;
 Objects.equals(str, "hjw") // false

1.2. 整型包装类的比较

所有整型包装类对象值的比较必须使用equals方法。

 Integer i = new Integer(10);
 Integer j = new Integer(10);
 System.out.println(i == j); // false

1.3. BigDecimal

1.3.1. BigDecimal 的用处

《阿里巴巴Java开发手册》中提到:浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。 具体原理和浮点数的编码方式有关,这里就不多提了,我们下面直接上实例:

 float f1 = 1.0f - 0.9f;
 float f2 = 0.9f - 0.8f;
 System.out.println(f1); // 0.100000024
 System.out.println(f2); // 0.099999964
 System.out.println(f1 == f2); // false
 ​
 double d1 = 1.0f - 0.9f;
 double d2 = 0.9f - 0.8f;
 System.out.println(d1); // 0.10000002384185791
 System.out.println(d2); // 0.09999996423721313
 System.out.println(d1 == d2); // false
 ​
 double d1 = 1.0 - 0.9;
 double d2 = 0.9 - 0.8;
 System.out.println(d1); // 0.09999999999999998
 System.out.println(d2); // 0.09999999999999998
 System.out.println(d1 == d2); // true

以上三个例子我们很清楚的可以看到使用了floatdouble的值在运算的时候回出现精度丢失,因为二进制是无法精确表示大部分的十进制小数。

 BigDecimal b1 = new BigDecimal("0.1");
 BigDecimal b2 = new BigDecimal("0.2");
 BigDecimal b3 = new BigDecimal("0.3");
 BigDecimal b32 = b3.subtract(b2);
 BigDecimal b21 = b2.subtract(b1);
 System.out.println(b32); // 0.1
 System.out.println(b21); // 0.1
 System.out.println(Objects.equals(b32, b21)); // true

1.3.2. BigDecimal 的大小比较

a.compareTo(b):返回-1表示a<b,0表示 a=b, 1表示a>b

 BigDecimal bigDecimal = new BigDecimal("01");
 BigDecimal bigDecimal1 = new BigDecimal("0.44");
 System.out.println(bigDecimal); // 1
 System.out.println(bigDecimal1); // 0.44
 System.out.println(bigDecimal.compareTo(bigDecimal1)); // 1

1.3.3. BigDecimal 保留几位小数

 BigDecimal bigDecimal = new BigDecimal("01");
 BigDecimal bigDecimal1 = new BigDecimal("0.44446");
 BigDecimal bigDecimal2 = bigDecimal1.setScale(3, BigDecimal.ROUND_HALF_UP); 
 System.out.println(bigDecimal); // 1
 System.out.println(bigDecimal1); // 0.44446
 System.out.println(bigDecimal2); // 0.444
 System.out.println(bigDecimal.compareTo(bigDecimal1)); // 1

1.3.4. BigDecimal 的使用注意事项

注意:我们在使用BigDecimal时,为了防止精度丢失,推荐使用它的 BigDecimal(String) 构造方法来创建对象。《阿里巴巴Java开发手册》对这部分内容也有提到如下图所示。

1.3.5. 总结

BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。

BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念

1.4. 基本数据类型与包装数据类型的使用标准

Reference:《阿里巴巴Java开发手册》

  • 【强制】所有的 POJO类属性必须使用包装数据类型。
  • 【强制】RPC方法的返回值和参数必须使用包装数据类型
  • 【推荐】所有的局部变量使用级别数据类型

比如我们定义一个学生,有一个属性是score,他这次缺考了,我们应该给null,如果使用了int,那么他显示的0分,这是不对的。

2. 集合

2.1. Arrays.asList() 使用指南

2.1.1. 简介

:使用Arrays.asList无法直接将数组转化为集合,而且无法将获得的集合添加或者移除元素,若执行了会报错!

2.1.2. 《阿里巴巴Java开发手册》对其的描述

Arrays.asList()将数组转换为集合后,底层其实还是数组,《阿里巴巴Java 开发手册》对于这个方法有如下描述:

2.1.3. 使用时的注意事项总结

传递的数组必须是对象数组,而不是基本类型。

Arrays.asList()是泛型方法,传入的对象必须是对象数组。

使用集合的修改方法:add()remove()clear()会抛出异常。

2.1.4. 如何正确的将数组转换为ArrayList?

2. 最简便的方法(推荐)

 List list = new ArrayList<>(Arrays.asList("a", "b", "c"))

2.2. Collection.toArray()方法使用的坑&如何反转数组

2.3. 不要在 foreach 循环里进行元素的 remove/add 操作

如果需要通过循环删除或者添加元素,请使用迭代器

 List<String> list = new ArrayList<>();
         list.add("1");
         list.add("2");
         Iterator<String> iterator = list.iterator();
         while (iterator.hasNext()) {
             if ("2".equals(iterator.next())) {
 ​
                 iterator.remove();
             }
         }
 //        for (String item: list) {
 //            if ("2".equals(item)) {
 //                list.remove(item);
 //            }
 //        }
         System.out.println(list.toString());