心灵鸡汤
整理一下自己的心情,忘记那些不愉快的往事,听听音乐,看看风景,说能说的话,做可做的事,走该走的路,见想见的人
# 一:遍历
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
for (String string : list) {
System.out.println(string);
}
String[] strings = new String[]{"3", "4", "5"};
for (String string : strings) {
System.out.println(string);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
查看上面编译后的源码:
public static void main(String[] args) {
List<String> list = (List)IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for(int i = 0; i < list.size(); ++i) {
System.out.println((String)list.get(i));
}
Iterator var7 = list.iterator();
while(var7.hasNext()) {
String string = (String)var7.next();
System.out.println(string);
}
String[] strings = new String[]{"3", "4", "5"};
String[] var9 = strings;
int var4 = strings.length;
for(int var5 = 0; var5 < var4; ++var5) {
String string = var9[var5];
System.out.println(string);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
可见,foreach循环时,数组使用的还是原始 for 循环,集合使用的是 Iterator 迭代器。
# 二:删除元素
使用for循环
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for (int i = 0; i < list.size(); i++) {
list.remove("2");
}
System.out.println("List剩余元素个数:" + list.size());
System.out.println("List剩余元素:" + list);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
运行结果:
使用foreach:
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for (String string : list) {
list.remove("2");
}
System.out.println("List剩余元素个数:" + list.size());
System.out.println("List剩余元素:" + list);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
运行结果:
查看上面编译后的源码:
public static void main(String[] args) {
List<String> list = (List)IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
Iterator var2 = list.iterator();
while(var2.hasNext()) {
String string = (String)var2.next();
list.remove("2");
}
System.out.println("List剩余元素个数:" + list.size());
System.out.println("List剩余元素:" + list);
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
运行报错,原因:
迭代器内部的每次遍历都会记录List内部的modcount当做预期值,然后在每次循环中用预期值与List的成员变量modCount作比较,但是普通list.remove调用的是List的remove,这时modcount++,但是iterator内记录的预期值=并没有变化,所以会报错。
所以,如果想要删除元素的话,需要使用迭代器内部的remove方法,如下所示:
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String next = it.next();
if (next.equals("2")) {
// 这里使用的是迭代器里面的remove()方法
it.remove();
}
}
System.out.println("List剩余元素个数:" + list.size());
System.out.println("List剩余元素:" + list);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
运行结果:
如果条件简单的话,可以使用Lambda表达式:
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
list.removeIf(next -> next.equals("2"));
System.out.println("List剩余元素个数:" + list.size());
System.out.println("List剩余元素:" + list);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
使用的API Collection<E>:
public interface Collection<E> extends Iterable<E> {
/**
* 删除此集合中满足给定Predicate的所有元素。在迭代期间或由Predicate引发的错误或运行时异常将转发给调用者。
* @implSpec
* 默认实现使用其iterator遍历集合的所有元素。使用Iterator.remove()删除每个匹配元素。如果集合的迭代器不支持删除,则将在第一个匹配元素上抛出UnsupportedOperationException
* @param filter 为要删除的元素返回true的Predicate
* @return 如果删除了任何元素,则为true
* @throws NullPointerException 如果指定的过滤器为空
* @throws UnsupportedOperationException 如果无法删除匹配的元素,或者通常不支持删除,则实现可能会抛出此异常
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
运行结果:
# 三:修改元素
使用for:
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for (int i = 0; i < list.size(); i++) {
list.set(i, "123");
}
list.forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
运行结果:
使用foreach:
public static void main(String[] args) {
List<String> list = IntStream.range(0, 3).mapToObj(String::valueOf).collect(Collectors.toList());
for (String string : list) {
string = "123";
}
list.forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
运行结果:
看结果,是无法修改了,那么如果修改元素的属性看是否可以?
创建一个学生类:
public class Student {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public Student setId(int id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
测试代码:
public static void main(String[] args) {
List<Student> list = IntStream.range(0, 3).mapToObj(id -> new Student(id, "张三" + id)).collect(Collectors.toList());
for (Student student : list) {
student.setName("李四" + student.getId());
}
list.forEach(System.out::println);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 四:小结
for与foreach都可以遍历数组/集合,不过for则在较复杂的循环中效率更高。
foreach不可以删除/修改集合元素,而for可以
foreach和for都可以修改元素里面的属性
所以相比较下来for循环更为灵活