我正在参加「掘金·启航计划」
static 代码块执行顺序
代码块加载顺序
- 静态代码块
static{}
类加载的时候执行,是最早被执行的,优先级最高 - 构造代码块
{}
构造代码块在每一次创建对象时执行,始终在构造方法前执行 - 构造方法 新建对象时调用,new 关键字创建对象的时候
问题:如下代码的加载顺序应该是如何?
class Static {
public static Static t1 = new Static();
{
System.out.println("构造块");
}
static {
System.out.println("静态块");
}
}
Static s = new Static();
// 构造块
// 静态块
// 构造块
按照我们的理解加载的逻辑应该是 : 静态代码块 static{}
> 构造代码块 {}
> 构造方法
为什么顺序没有按照我们的理解去输出。原因在于 public static Static t1 = new Static();
,因为此静态代码块在执行的时候创建了对象。所以才有构造块在静态块之前执行了。将上面代码改成如下就会正常输出了
class Static {
{
System.out.println("构造块");
}
static {
System.out.println("静态块");
}
public static Static t1 = new Static();
}
Static s = new Static();
// 静态块
// 构造块
// 构造块
父类代码块加载顺序
先看个例子 A 继承 B:
class B {
public B() {
super();
System.out.println("构造器B");
}
{
System.out.println("普通的代码块B");
}
static {
System.out.println("静态代码块B");
}
}
class A extends B {
public A() {
super();
System.out.println("构造器A");
}
{
System.out.println("普通的代码块A");
}
static {
System.out.println("静态代码块A");
}
}
A a = new A();
// 静态代码块B
// 静态代码块A
// 普通的代码块B
// 构造器B
// 普通的代码块A
// 构造器A
总结:父类静态代码块 > 子类静态代码块 > 父类代码块 > 父类构造方法 > 子类代码块 > 子类构造方法
只要记住代码块的加载顺序,耐心分析就可以推断出结论。永远相信计算机是按照规则执行并不会出现诡异的事情。
ArrayList 删除元素
ArrayList remove 方法使用很简单。有两种实现
- 根据数组的下标删除
remove(int index)
- 根据数组内的元素删除
remove(Object o)
删除最终的执行都是上图的方法,根据数组元素的下表做一次数组的拷贝(实际上是数组的元素向前移动,最后一位置为 null )。看下面这个例子
数组循环中删除元素
期待的结果是移除下标为偶数的元素,但是如下代码的结果却不是想要的结果。
问题:每次迭代数组的长度都会改变,就导致执行结果不准确。
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8));
for (int i = 0; i < list.size(); i++) {
if (i % 2 == 0) {
list.remove(i);
}
}
System.out.println(list); // [2, 3, 5, 6, 8]
解决:对于此类问题我们只需要列表从后往前遍历
for (int i = list.size() - 1; i >= 0; i--) {
if (i % 2 == 0) {
list.remove(i);
}
}
System.out.println(list); // [2, 4, 6, 8]
数组重复元素的删除
期待的结果 remove 所有相同的元素。
问题:数组中存在重复元素,如何一次性全部移除
List<String> list = new ArrayList<>(Arrays.asList("1", "1", "1", "2", "3"));
list.remove("1");
System.out.println(list); // [1, 1, 2, 3]
解决:使用 removeIf
List<String> list = new ArrayList<>(Arrays.asList("1", "1", "1", "2", "3"));
list.removeIf(o -> o.equals("1"));
System.out.println(list); // [2, 3]