Java Foundation (those accustomed to the lack of principle do not know where)

First, the basic

1.1 correct use equals method

     equals method of Object readily shorting pointer exception, should be used with a constant or a value determined object equals to call. The following code

     

// can not use a null value to a reference type variable non-static method call, otherwise an exception is thrown 
String STR = null ;
 IF (str.equals ( "SnailClimb" )) { 
  ... 
} the else { 
  .. 
} 



/ / run the above procedures throws a null pointer exception, but we determined the conditions of the second row to the statement following this case, it will not throw a null pointer exception, else block of statements is executed. 

"SnailClimb" .equals (str); // false 


// But more is recommended java.util.Objects # equals (JDK7 introduced tools). 

Objects.equals ( null , "SnailClimb"); // to false 



Source: 
public  static  Boolean the equals (Object A, Object B) {
         // avoid null pointer exception. If at this time, then a == null a.equals (b) will not be implemented to avoid a null pointer exception.
        return (a == b) || (a != null && a.equals(b));
    }

 

.equals (before) entered after the equals method when you call, be sure to follow the "constant" .equals (variable) or. This will avoid a null pointer error, usually pay more attention to cultivate the habit, prevent future lay hidden.

Knowledge supplement

About null, you have to know a few things:

1, null is Java keywords, such as public, static, final. It is case-sensitive, you can not write null Null or NULL, the compiler will not recognize them and error.

2, just as each primitive type has a default value, such as int The default value is 0, boolean default value is false, null is the default value for any reference type, strictly speaking, is not the default for all object types. As you create a Boolean variable, it will be false as their default values, Java Any reference variables are null as the default. This is applicable for all variables, such as member variables, local variables, instance variables, static variables (but you use an uninitialized local variables, the compiler will warn you). To prove this fact, you can then print its value by creating a variable to observe the reference variables.

. 3, neither null nor a type of the object, it is only a special value, which you can impart any reference type, you can also be converted to any type null.

4, null can be assigned to a reference variable, you can not assign null basic types of variables, such as int, double, float, boolean. If you do that, the compiler will report an error.

5, any packaging containing the null value generating basic data types Java unpacking time throws a null pointer exception. (For example, Integer unpacking as int)

6, if a reference type variable with a null value, the instanceof operation will return false. (Instanceof: to point out at runtime if an object is an instance of a particular class, such as: Integer num = null, then returns false when calling num instanceof Integer)

7, can not call non-static method to use a null value of a reference type variable, it will throw a null pointer exception; you can use the static method to use a null value of a reference type variable, because the static method uses static binding, do not throw a null pointer exception.

8, you can use or ==! = Null value comparison operation, but can not use the algorithms or other logical operations, such as less than or greater than. Not the same as SQL, will return true in Java null == null.

 

1.2 Comparison packaging integer value

 All packaging Integer Comparison object value equals method must be used.

1 Integer x = 3;
2 Integer y = 3;
3 System.out.println(x == y);// true
4 Integer a = new Integer(3);
5 Integer b = new Integer(3);
6 System.out.println(a == b);//false
7 System.out.println(a.equals(b));//true

When creating an Integer object using automatic packing mode, when the value at -128 ~ 127, Integer cached objects will be created, when the value again next time, corresponding to the Integer object taken directly from the cache. Therefore, the code above, x and y refer to the same Integer object.

Note: If Alibaba p3c plug-in installed on your IDE (IDEA / Eclipse), this plugin if you use == detected, then will prompt an error, it is recommended to install a plug-in, very good.

 

 

1.3BigDecimal

 1.3.1. BigDecimal usefulness

"Ali Baba Java Development Manual" referred to: determine the equivalence between the float, the basic data types can not be used == to compare, packaging data types can not be judged by equals. Specific principles and coding float about here is not to mention, we direct the following examples:

1 float a = 1.0f - 0.9f;
2 float b = 0.9f - 0.8f;
3 System.out.println(a);// 0.100000024
4 System.out.println(b);// 0.099999964
5 System.out.println(a == b);// false

We have a basic knowledge of mathematics clearly know that the output is not what we want (loss of precision), how do we solve this problem? A very common method is: BigDecimal to define that use floating-point number, then the floating-point arithmetic operation.

BigDecimal a = new BigDecimal("1.0");
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 

1.3.2. Compare the size of BigDecimal

a.compareTo(b) : -1 to indicate less than, equal to 0 indicates, that is greater than 1.

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.compareTo(b));// 1

1.3.3. BigDecimal reserved several decimal places

By  setScaleretains several decimal places and ways to set retention rules. There are quite a variety, no record retention rules, IDEA will be prompted.

BigDecimal m = new BigDecimal("1.255433");
BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
System.out.println(n);// 1.255

1.3.4. BigDecimal precautions for use

Note: we use BigDecimal, in order to prevent loss of precision, it is recommended to use the BigDecimal (String) constructor to create the object. "Ali Baba Java Development Manual," this part of the content is also mentioned as shown below.

 

 

1.3.5 Summary

BigDecimal is mainly used to operate (large) float, BigInteger primarily used to operate large integer (long type over).

BigDecimal to achieve using BigInteger, the difference is added to the concept BigDecimal decimal places

 

1.4. Basic data types and data types of packaging using standard

Reference: "Ali Baba Java Development Manual"

  • [Mandatory] All POJO class property must use packaging data type.
  • [Force] RPC parameter and return value data type packaging must be used.
  • [Recommended] all local variables using the basic data types.

For example, if we customized a Student class, which has a property that achievement score, if Integer instead of int definitions, exam, students may not test the value is null, it may test, but exam 0, value is 0, the expression of these two states is obviously not the same.

说明 :POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何 NPE 问题,或者入库检查,都由使用者来保证。

正例 : 数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险。

反例 : 比如显示成交总额涨跌情况,即正负 x%,x 为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示为 0%,这是不合理的,应该显示成中划线。所以包装数据类型的 null 值,能够表示额外的信息,如:远程调用失败,异常退出。

 

2. 集合

2.1. Arrays.asList()使用指南

Arrays.asList()在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。

String[] myArray = { "Apple", "Banana", "Orange" }; 
List<String> myList = Arrays.asList(myArray);
//上面两个语句等价于下面一条语句
List<String> myList = Arrays.asList("Apple","Banana", "Orange");

JDK 源码对于这个方法的说明:

/**
 *返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
 */ 
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

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

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

 

 

2.1.3. 使用时的注意事项总结
传递的数组必须是对象数组,而不是基本类型。

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

1 int[] myArray = { 1, 2, 3 };
2 List myList = Arrays.asList(myArray);
3 System.out.println(myList.size());//1
4 System.out.println(myList.get(0));//数组地址值
5 System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException
6 int [] array=(int[]) myList.get(0);
7 System.out.println(array[0]);//1

当传入一个原生数据类型数组时,Arrays.asList() 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。

我们使用包装类型数组就可以解决这个问题。

Integer[] myArray = { 1, 2, 3 };

使用集合的修改方法: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 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法

 

List myList = Arrays.asList(1, 2, 3);
System.out.println(myList.getClass());//class java.util.Arrays$ArrayList

下图是java.util.Arrays$ArrayList的简易源码,我们可以看到这个类重写的方法有哪些。

 private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        ...

        @Override
        public E get(int index) {
          ...
        }

        @Override
        public E set(int index, E element) {
          ...
        }

        @Override
        public int indexOf(Object o) {
          ...
        }

        @Override
        public boolean contains(Object o) {
           ...
        }

        @Override
        public void forEach(Consumer<? super E> action) {
          ...
        }

        @Override
        public void replaceAll(UnaryOperator<E> operator) {
          ...
        }

        @Override
        public void sort(Comparator<? super E> c) {
          ...
        }
    }

我们再看一下java.util.AbstractListremove()方法,这样我们就明白为啥会抛出UnsupportedOperationException

public E remove(int index) {
    throw new UnsupportedOperationException();
}

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

1. 自己动手实现(教育目的)

//JDK1.5+
static <T> List<T> arrayToList(final T[] array) {
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) {
    l.add(s);
  }
  return (l);
}



Integer [] myArray = { 1, 2, 3 };
System.out.println(arrayToList(myArray).getClass());//class java.util.ArrayList

 

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

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

3. 使用 Java8 的Stream(推荐)

Integer [] myArray = { 1, 2, 3 };
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 = { 1, 2, 3 };
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

 

4. 使用 Guava(推荐)

对于不可变集合,你可以使用ImmutableList类及其of()与copyOf()工厂方法:(参数不能为空)

List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array

对于可变集合,你可以使用Lists类及其newArrayList()工厂方法:

List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

2.2. Collection.toArray()方法使用的坑&如何反转数组
该方法是一个泛型方法:<T> T[] toArray(T[] a); 如果toArray方法中没有传递任何参数的话返回的是Object类型数组。

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]);//没有指定类型的话会报错

由于JVM优化,new String[0]作为Collection.toArray()方法的参数现在使用更好,new String[0]就是起一个模板的作用,指定了返回数组的类型,0是为了节省空间,因为它只是为了说明返回的类型。详见:https://shipilev.net/blog/2016/arrays-wisdom-ancients/

 

2.3. 不要在 foreach 循环里进行元素的 remove/add 操作
如果要进行remove操作,可以调用迭代器的 remove方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add方法,迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。

fail-fast 机制 :多个线程对 fail-fast 集合进行修改的时,可能会抛出ConcurrentModificationException,单线程下也会出现这种情况,上面已经提到过。

java.util包下面的所有的集合类都是fail-fast的,而java.util.concurrent包下面的所有的类都是fail-safe的。

 

 

  

Guess you like

Origin www.cnblogs.com/pengthrree/p/11989960.html