文章目录
说明:本文是校招复习系列文章,参考文献做统一说明!
整体目录详见:校招复习目录
1. 正确使用 equals 方法
Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。
不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常 !
例如:
String str = null;
if (str.equals("SnailClimb")) {
...
} else {
..
}
这样会报错,应该改为常量或确定有值的对象来调用 equals,SnailClimb".equals(str);
。
也可以使用工具类Objects.equals(null,"SnailClimb");
2. 整型包装类值的比较
包装类对象,如果要比较值,必须使用equals方法,这样就不会有意外发生。
因为针对一个引用类型的对象,== 比较的是内存中的地址值,所以Integer 如果是new 出来的情况下,就会使得a2和b2的地址值不一致,然后判断为false。而equals()方法则不会出现该问题,他是去比较包装类的具体值。
Integer a1 = 3;
Integer b1 = 3;
System.out.println(a1 == b1); //true
System.out.println(a1.equals(b1)); //true
Integer a2 = new Integer(3);
Integer b2 = new Integer(3);
System.out.println(a2 == b2); //false
System.out.println(a2.equals(b2)); //true
如果是基础数据类型,那么equals方法是没有的,只可以使用==,比较的是数值。
即便是第二种情况,即使实例是new Integer() ,但是由于会拆箱变成基础数据类型,所以仍旧没有地址值,只有数值。
int a =3;
int b =3;
System.out.println(a == b); //true
int a3 = new Integer(3);
int b3 = new Integer(3);
System.out.println(a3==b3); // true
3. BigDecimal
(1)BigDecimal 的用处
《阿里巴巴Java开发手册》中提到:浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。 具体原理和浮点数的编码方式有 关。
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999964
System.out.println(a == b);// false
具有基本数学知识的我们很清楚的知道输出并不是我们想要的结果(精度丢失),我们如何解决这个问题呢?一种很常用的方法是:使用使用 BigDecimal (String s)来定义浮点数的值,再进行浮点数的运算操作。
使用普通的BigDecimal(double val)仍旧可能会丢失精度。
BigDecimal a = new BigDecimal("1.0"); //String
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");
BigDecimal x = a.subtract(b);// 0.1
BigDecimal y = b.subtract(c);// 0.1
System.out.println(x.equals(y));// true
(2)BigDecimal 的大小比较
a.compareTo(b)
: 返回 -1 表示小于,0 表示 等于, 1表示 大于。
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.compareTo(b)); // 1
BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。
BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念。
4. 基本数据类型与包装数据类型的使用标准
- 【强制】所有的 POJO 类属性必须使用包装数据类型。
- 【强制】RPC 方法的返回值和参数必须使用包装数据类型。
- 【推荐】所有的局部变量使用基本数据类型。
-
POJO 类,Plain Old Java Object。这个名字用来强调它是一个普通java对象,而不是一个特殊的对象 。
-
理论上讲,任何一个 Java 类都可以是一个 Bean 。JavaBean则比 POJO复杂很多, Java Bean 是可复用的组件,对 Java Bean 并没有严格的规范,但通常情况下,由于 Java Bean 是被容器所创建(如 Tomcat) 的,所以 Java Bean 应具有一个无参的构造器,另外,通常 Java Bean 还要实现 Serializable 接口用于实现 Bean 的持久性。
-
远程过程调用RPC,就是客户端基于某种传输协议通过网络向服务提供端请求服务处理,然后获取返回数据(对于ONE WAY模式则不返还响应结果); Java界的RPC中间件百家争鸣,国内开源的就有阿里的Dubbo(当当二次开发的DubboX),新浪Motan;国外跨语言的有Facebook的Thrift, Google的gRpc等。
比如我们如果自定义了一个Student类,其中有一个属性是成绩score,如果用Integer而不用int定义,一次考试学生可能没考,值是null,也可能考了,但考了0分,值是0。这两个表达的状态明显不一样.
5. Arrays.asList()使用指南
(1)简介
Arrays.asList()
在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。
String[] arr2 = new String[]{"apple","peach","banar"};
List<String> strings = Arrays.asList(arr2);
(2)使用事项
Arrays.asList()
是泛型方法,传入的对象必须是对象数组,而不是基本类型。
int[] arr1 = {3,5,1,7};
//List ints = Arrays.asList(arr1);
List<int[]> ints = Arrays.asList(arr1);
Integer[] arr3 = {4,2,6,9};
List<Integer> integers = Arrays.asList(arr3);
可以看出使用int[]数组时,需要将整个数组作为一个对象;
而使用包装类型的Integer[]时,只需要将Integer作为对象即可。
使用集合的修改方法:add()、remove()、clear()会抛出异常。
List myList = Arrays.asList(1, 2, 3);
myList.add(4);//运行时报错:UnsupportedOperationException
myList.remove(1);//运行时报错:UnsupportedOperationException
myList.clear();//运行时报错:UnsupportedOperationException
Arrays.asList()
方法返回的并不是 java.util.ArrayList
,而是 java.util.Arrays
的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。
(3) 如何正确的将数组转换为ArrayList?
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
6. Collection.toArray() 如何反转数组
String [] s= new String[]{
"dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A"
};
List<String> list = Arrays.asList(s);
Collections.reverse(list);
// s=list.toArray(new String[0]);
// new String[0]是为了将Object类型转换为String,0是为了节省空间,因为它只是为了说明返回的类型
// 另外不写这一句,发现原始s 也已经倒序排列好了!
7. 不要在 foreach 循环里进行元素的 remove/add 操作
如果要进行remove
操作,可以调用迭代器的 remove
方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add
方法,迭代器都将抛出一个ConcurrentModificationException
,这就是单线程状态下产生的 fail-fast 机制。 如果并发操作需要对Iterator对象加锁。
List<String> list = new ArrayList<>();
list.add("apple");
list.add("peach");
list.add("pear");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String next = it.next();
if (next.equals("apple")){
it.remove();
}
}
// 报 ConcurrentModificationException
for (String li:list){
if ("peach".equals(li)){
list.remove(li);
}
}
另外一种错误:java.lang.UnsupportedOperationException
在之前的asList( )的基础上,直接使用iterator。Java.lang.UnsupportedOperationException是不支持功能异常,常常出现在使用Arrays.asList()后调用add,remove这些method时。Arrays$ArrayList没有override remove(int),add(int)等,所以throw UnsupportedOperationException。
String[] arr2 = new String[]{"apple","peach","banar"};
List<String> strings = Arrays.asList(arr2);
Collections.reverse(strings);
arr2 = strings.toArray(new String[0]);
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String next = iterator.next();
while ("apple".equals(next)){
iterator.remove();
}
}