1-1-2 Java基础知识疑难点

说明:本文是校招复习系列文章,参考文献做统一说明!
整体目录详见:校招复习目录

1. 正确使用 equals 方法

Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。

不能使用一个值为null的引用类型变量来调用非静态方法,否则会抛出异常 !

例如:

    String str = null;
    if (str.equals("SnailClimb")) {
      ...
    } else {
      ..
    }

这样会报错,应该改为常量或确定有值的对象来调用 equalsSnailClimb".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 方法的返回值和参数必须使用包装数据类型。
  • 【推荐】所有的局部变量使用基本数据类型。
  1. POJO 类,Plain Old Java Object。这个名字用来强调它是一个普通java对象,而不是一个特殊的对象 。

  2. 理论上讲,任何一个 Java 类都可以是一个 Bean 。JavaBean则比 POJO复杂很多, Java Bean 是可复用的组件,对 Java Bean 并没有严格的规范,但通常情况下,由于 Java Bean 是被容器所创建(如 Tomcat) 的,所以 Java Bean 应具有一个无参的构造器,另外,通常 Java Bean 还要实现 Serializable 接口用于实现 Bean 的持久性

  3. 远程过程调用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();
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值