Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 37 additions & 14 deletions docs/java/Java疑难点.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ Objects.equals(null,"SnailClimb");// false
我们看一下`java.util.Objects#equals`的源码就知道原因了。
```java
public static boolean equals(Object a, Object b) {
// 可以避免空指针异常。如果a==null的话此时a.equals(b)就不会得到执行,避免出现空指针异常。
return (a == b) || (a != null && a.equals(b));
}
// 可以避免空指针异常。如果a==null的话此时a.equals(b)就不会得到执行,避免出现空指针异常。
return (a == b) || (a != null && a.equals(b));
}
```

**注意:**
Expand Down Expand Up @@ -104,14 +104,18 @@ System.out.println(a == b);// false
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

BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);

System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */
```

### 1.3.2. BigDecimal 的大小比较

`a.compareTo(b)` : 返回 -1 表示小于,0 表示 等于, 1表示 大于
`a.compareTo(b)` : 返回 -1 表示 `a` 小于 `b`,0 表示 `a` 等于 `b` , 1表示 `a` 大于 `b`

```java
BigDecimal a = new BigDecimal("1.0");
Expand Down Expand Up @@ -167,7 +171,7 @@ Reference:《阿里巴巴Java开发手册》
`Arrays.asList()`在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。

```java
String[] myArray = { "Apple", "Banana", "Orange" };
String[] myArray = {"Apple", "Banana", "Orange"};
List<String> myList = Arrays.asList(myArray);
//上面两个语句等价于下面一条语句
List<String> myList = Arrays.asList("Apple","Banana", "Orange");
Expand All @@ -177,8 +181,9 @@ JDK 源码对于这个方法的说明:

```java
/**
*返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
*/
*返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,
* 与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
*/
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
Expand All @@ -197,20 +202,20 @@ public static <T> List<T> asList(T... a) {
`Arrays.asList()`是泛型方法,传入的对象必须是对象数组。

```java
int[] myArray = { 1, 2, 3 };
int[] myArray = {1, 2, 3};
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));//数组地址值
System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException
int [] array=(int[]) myList.get(0);
int[] array = (int[]) myList.get(0);
System.out.println(array[0]);//1
```
当传入一个原生数据类型数组时,`Arrays.asList()` 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。

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

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

**使用集合的修改方法:`add()`、`remove()`、`clear()`会抛出异常。**
Expand Down Expand Up @@ -296,7 +301,7 @@ static <T> List<T> arrayToList(final T[] array) {
for (final T s : array) {
l.add(s);
}
return (l);
return l;
}
```

Expand Down Expand Up @@ -344,6 +349,14 @@ List<String> list = new ArrayList<String>();
CollectionUtils.addAll(list, str);
```

**6. 使用 Java9 的 `List.of()`方法**
``` java
Integer[] array = {1, 2, 3};
List<Integer> list = List.of(array);
System.out.println(list); /* [1, 2, 3] */
/* 不支持基本数据类型 */
```

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

该方法是一个泛型方法:`<T> T[] toArray(T[] a);` 如果`toArray`方法中没有传递任何参数的话返回的是`Object`类型数组。
Expand All @@ -365,6 +378,16 @@ s=list.toArray(new String[0]);//没有指定类型的话会报错

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

Java8开始,可以使用`Collection#removeIf()`方法删除满足特定条件的元素,如
``` java
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; ++i) {
list.add(i);
}
list.removeIf(filter -> filter % 2 == 0); /* 删除list中的所有偶数 */
System.out.println(list); /* [1, 3, 5, 7, 9] */
```

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

![不要在 foreach 循环里进行元素的 remove/add 操作](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019/7/foreach-remove:add.png)
Expand Down
22 changes: 13 additions & 9 deletions docs/java/basic/final,static,this,super.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public class Sub extends Super {

**使用 this 和 super 要注意的问题:**

- 在构造器中使用 `super()` 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。
- 在构造器中使用 `super()` 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。
- this、super不能用在static方法中。

**简单解释一下:**
Expand Down Expand Up @@ -141,7 +141,7 @@ public class StaticBean {
this.name = name;
}
//静态方法
static void SayHello() {
static void sayHello() {
System.out.println("Hello i am java");
}
@Override
Expand All @@ -164,7 +164,7 @@ public class StaticDemo {
StaticBean.age = 33;
System.out.println(staticBean + " " + staticBean2 + " " + staticBean3 + " " + staticBean4);
//StaticBean{name=1,age=33} StaticBean{name=2,age=33} StaticBean{name=3,age=33} StaticBean{name=4,age=33}
StaticBean.SayHello();//Hello i am java
StaticBean.sayHello();//Hello i am java
}

}
Expand All @@ -173,7 +173,7 @@ public class StaticDemo {

### 静态代码块

静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块非静态代码块构造方法)。 该类不管创建多少对象,静态代码块只执行一次.
静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块 —> 非静态代码块 —> 构造方法)。 该类不管创建多少对象,静态代码块只执行一次.

静态代码块的格式是

Expand Down Expand Up @@ -274,7 +274,11 @@ class Foo {

}
```
你可以像这样调用静态方法:`Foo.method1()`。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行:`Foo bar = new Foo(1);bar.method2();`
你可以像这样调用静态方法:`Foo.method1()`。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行
``` java
Foo bar = new Foo(1);
bar.method2();
```

总结:

Expand All @@ -285,7 +289,7 @@ class Foo {

相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。

不同点: 静态代码块在非静态代码块之前执行(静态代码块非静态代码块构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。
不同点: 静态代码块在非静态代码块之前执行(静态代码块 -> 非静态代码块 -> 构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。

> 修正 [issue #677](https://github.com/Snailclimb/JavaGuide/issues/677):静态代码块可能在第一次new的时候执行,但不一定只在第一次new的时候执行。比如通过 `Class.forName("ClassDemo")`创建 Class 对象的时候也会执行。

Expand Down Expand Up @@ -347,6 +351,6 @@ public class Test {

### 参考

- httpsblog.csdn.netchen13579867831articledetails78995480
- httpwww.cnblogs.comchenssyp3388487.html
- httpwww.cnblogs.comQian123p5713440.html
- https://blog.csdn.net/chen13579867831/article/details/78995480
- https://www.cnblogs.com/chenssy/p/3388487.html
- https://www.cnblogs.com/Qian123/p/5713440.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ public class Pizza {
}

public boolean isDeliverable() {
if (getStatus() == PizzaStatus.READY) {
return true;
}
return false;
return getStatus() == PizzaStatus.READY;
}

// Methods that set and get the status variable.
Expand All @@ -63,9 +60,9 @@ public class Pizza {

## 3.使用 == 比较枚举类型

由于枚举类型确保JVM中仅存在一个常量实例,因此我们可以安全地使用“ ==”运算符比较两个变量,如上例所示;此外,“ ==”运算符可提供编译时和运行时的安全性。
由于枚举类型确保JVM中仅存在一个常量实例,因此我们可以安全地使用 `==` 运算符比较两个变量,如上例所示;此外,`==` 运算符可提供编译时和运行时的安全性。

首先,让我们看一下以下代码段中的运行时安全性,其中“ ==”运算符用于比较状态,并且如果两个值均为null 都不会引发 NullPointerException。相反,如果使用equals方法,将抛出 NullPointerException:
首先,让我们看一下以下代码段中的运行时安全性,其中 `==` 运算符用于比较状态,并且如果两个值均为null 都不会引发 NullPointerException。相反,如果使用equals方法,将抛出 NullPointerException:

```java
if(testPz.getStatus().equals(Pizza.PizzaStatus.DELIVERED));
Expand All @@ -84,9 +81,12 @@ if(testPz.getStatus() == TestColor.GREEN);
```java
public int getDeliveryTimeInDays() {
switch (status) {
case ORDERED: return 5;
case READY: return 2;
case DELIVERED: return 0;
case ORDERED:
return 5;
case READY:
return 2;
case DELIVERED:
return 0;
}
return 0;
}
Expand Down