List是我们在工作场景中使用的类型中最多的一个啦,有很多场景需要我们在List中删除一个或某个元素,那么我们该如何正确无误的删除List中的元素呢,下面通过学习老项目中前辈们留下的代码总结出如下几种方式
准备数据,我们通过代码来说明,首先我们需要准备一下数据
List<String> list = new ArrayList<>();
@Before
public void init() {
list.add("zhangsan1");
list.add("zhangsan2");
list.add("lisi1");
list.add("lisi2");
list.add("wangwu1");
list.add("wangwu2");
list.add("zhaoliu1");
list.add("zhaoliu2");
}
通过for循环-不可取的方式
直接使用简单for循环,这种方式可能会在遍历的过程中漏掉部分元素,从而出现少删的情况
@Test
public void by_remove_fist() {
// 这样实现有问题,模拟删除第一个元素
for (int i = 0; i < list.size(); i++) {
if (list.get(i).startsWith("zhangsan1")) {
list.remove(i);
}
}
List<String> expected = Arrays.asList("zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2", "zhaoliu1", "zhaoliu2");
Assert.assertThat(expected, CoreMatchers.is(list));
}
@Test
public void by_remove_last() {
// 这样实现有问题,模拟删除最后一个元素
for (int i = 0; i < list.size(); i++) {
if (list.get(i).startsWith("zhaoliu")) {
list.remove(i);
}
}
List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2", "zhaoliu2");
Assert.assertThat(list, CoreMatchers.is(expected));
}
@Test
public void by_remove_middle() {
// 这样实现有问题,模拟删除中间元素
for (int i = 0; i < list.size(); i++) {
if (list.get(i).startsWith("lisi")) {
list.remove(i);
}
}
List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi2", "wangwu1", "wangwu2", "zhaoliu1", "zhaoliu2");
Assert.assertThat(list, CoreMatchers.is(expected));
}
通过Stream的Filter
@Test
public void by_stream_filter() {
list = list.stream().filter(t -> !t.startsWith("zhaoliu")).collect(Collectors.toList());
List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
Assert.assertThat(list, CoreMatchers.is(expected));
}
通过removeIf
@Test
public void by_removeIf() {
list.removeIf(t -> t.startsWith("zhaoliu"));
List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
Assert.assertThat(list, CoreMatchers.is(expected));
}
通过Iterator
迭代器:迭代其实我们可以简单地理解为遍历,是一个标准 化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向每次遍历前都需要知道要遍历集合的内部结构。
@Test
public void by_iterator() {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.startsWith("zhaoliu")) {
iterator.remove();
}
}
List<String> expected = Arrays.asList("zhangsan1", "zhangsan2", "lisi1", "lisi2", "wangwu1", "wangwu2");
Assert.assertThat(list, CoreMatchers.is(expected));
}