1、语法
流程控制主要为判断if...esle if...else以及循环语句while、do...while和for循环
if...else语句主要进行判断。jdk8之后引入 optional类和函数式方法可以对if进行替换
//空值判断,替代if进行空置判断
String s1 = "abc";
Optional.ofNullable(s1).ifPresent(o -> {
System.out.println(o);
});
/*函数式编程,jdk8提供了四大函数式接口
consumer:消费者接口
supplier:供给者接口
function:函数式接口
predicate:断言式接口
*/
- 循环控制语句
while、do...while、forwhile和do...while的区别是后者先进行一次循环,然后进行判断- for循环和while循环都可进行替换
break、continue、 return都是跳出循环的意思。break是跳出整个循环,continue是跳出本次循环, return意味着方法的结束switch...case:可以替代if语句,他只能匹配整数值和字符串以及枚举类型。结束时必须有break或者return
2、foreach和fori的区别
- 数组
String[] arrays = {"a","b","c"};
for (String array : arrays) {
// System.out.println(array);
}
for (int i = 0; i < arrays.length; i++) {
// System.out.println(arrays[i]);
}
}
0 iconst_3 //数组长度
1 anewarray #6 <java/lang/String> //堆内创建数组,地址引用值压入栈顶
4 dup //复制栈顶值
5 iconst_0 //常量0入栈
6 ldc #7 <a> //常量a入栈
8 aastore //弹出栈顶的值、索引、数组引用进行赋值
9 dup
10 iconst_1
11 ldc #8 <b>
13 aastore
14 dup
15 iconst_2
16 ldc #9 <c>
18 aastore
19 astore_1
//foreach
20 aload_1 //数组变量进栈
21 astore_2 //赋值给第二个变量
22 aload_2 //第二个局部变量进栈
23 arraylength //获取数组长度
24 istore_3 //赋值给第三个局部变量
25 iconst_0 //常量0进栈
26 istore 4 //赋值给第四个局部变量
28 iload 4 //第四个局部变量进栈
30 iload_3 //第三个局部变量进栈
31 if_icmpge 46 (+15) //判断栈顶两个元素
34 aload_2 //第二个局部变量进栈
35 iload 4 //第四个局部变量进栈
37 aaload //数组对应索引的元素进栈
38 astore 5 //赋值给第五个局部变量
40 iinc 4 by 1 //第四个局部变量自增1
43 goto 28 (-15)
//fori
46 iconst_0
47 istore_2
48 iload_2
49 aload_1
50 arraylength
51 if_icmpge 60 (+9)
54 iinc 2 by 1
57 goto 48 (-9)
60 return
从指令可以看出,当对数组进行foreach和fori的时候,两者的原理实际上是相通的,foreach实际上还是调用的数组长度进行循环然后取值
- list集合
//arraylist
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
for (String s : list) {
}
for (int i = 0; i < list.size(); i++) {
}
//LinkedList
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("a");
linkedList.add("b");
for (String s : linkedList) {
}
for (int i = 0; i < linkedList.size(); i++) {
}
//看for循环部分的代码
22 aload_1 //加载局部变量1
23 invokevirtual #13 <java/util/ArrayList.iterator : ()Ljava/util/Iterator;> //调用iterator
26 astore_2 //赋值给第二个局部变量
27 aload_2 //加载局部变量
28 invokeinterface #14 <java/util/Iterator.hasNext : ()Z> count 1 //调用hasnext
33 ifeq 49 (+16) //判断
36 aload_2 //
37 invokeinterface #15 <java/util/Iterator.next : ()Ljava/lang/Object;> count 1
42 checkcast #6 <java/lang/String>
45 astore_3
46 goto 27 (-19)
//fori
49 iconst_0
50 istore_2
51 iload_2
52 aload_1
53 invokevirtual #16 <java/util/ArrayList.size : ()I>
56 if_icmpge 65 (+9)
59 iinc 2 by 1
62 goto 51 (-11)
87 aload_2
88 invokevirtual #20 <java/util/LinkedList.iterator : ()Ljava/util/Iterator;>
91 astore_3
92 aload_3
93 invokeinterface #14 <java/util/Iterator.hasNext : ()Z> count 1
98 ifeq 115 (+17)
101 aload_3
102 invokeinterface #15 <java/util/Iterator.next : ()Ljava/lang/Object;> count 1
107 checkcast #6 <java/lang/String>
110 astore 4
112 goto 92 (-20)
//fori
115 iconst_0
116 istore_3
117 iload_3
118 aload_2
119 invokevirtual #21 <java/util/LinkedList.size : ()I>
122 if_icmpge 131 (+9)
125 iinc 3 by 1
128 goto 117 (-11)
可以看出集合的遍历,foreach调用的是iterator,而fori是通过索引进行调用的。 需要注意的是fori获取数据,由于arraylist内部维护有索引,所以可以直接取到数据,但是linkedlist不同 我们可以通过get方法查看到
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
//可以看出linkedlist取数据的时候会进行遍历,所以就相当于foreach多了一层循环