谈到List,我们最常用也是最熟悉的就是List的遍历了。当然,其中还有其他对List 的数据处理,增删改查以及数据变换等等,可以说,每一个程序员几乎都或多或少的在使用List进行数据的处理或者说是优化,以达到自己期望的数据信息。今天有点时间,就简单的对List进行了简单的整理。
一、List 的遍历
总结下来有以下几种:
1.foreach
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
list.add("ac");
for (String str:list) {
//to do sth
}
这个就不多说了,大家都看得懂。
2.fori
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
list.add("ac");
for (int i = 0,j=list.size(); i < j; i++) {
// to do sth
}
这个插句话,大家一般使用fori的时候是这样的:
for (int i = 0; i < list.size(); i++) {
// to do sth
}
这样写当然也没有毛病,不过每次遍历都会去取一下list 的size(),对性能是有一定影响的,当然这个微乎其微,但是如果频繁使用 并且数据量大的话,不建议这样用,会增加耗时。如果事先将list.size()赋值给j,之后就不用再去取list的size()了,同时j位于方法区内,只进行了一次赋值,之后便可以在循环中一直使用,性能无无疑是会提升那么一丢丢的。
3.iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String next = iterator.next();
// to do sth
}
迭代器遍历这个大家应该也是比较熟悉的,这个一般是用来删除List 中的某个数据的,使用的是iterator.remove,在遍历过程中删除对List 并没有什么影响
4、stream
list.stream().forEach(str->{
//to do sth
});
stream()是JDK1.8 新增的一种处理一些数据的流,具有以下特点:
- 基于集合或者序列
- 流不存储值,也不能重复使用,数据通过管道的方式进行操作
- 每个操作都是函数式的,对流的操作不会影响源数据
- 多数操作(排序,映射,过滤等),可以延迟实现
当然,stream()之后还可以进行过滤(filter)、排序(groupingBy)、生成新的list等等,这里就不多说了,有兴趣的可以去看下JDK1.8 新特性lamada 表达式的应用
二、List对数据的删除
对于list 的删除,大家应该都有一定的了解,一定不能边遍历边删除,像这样的话
for (String str:list) {
if(str.equals("...")){
list.remove(str);
}
}
会出事的哦,所以我们尽量不要乱搞事情。主要的删除方法有已下几种:
1.使用iterator进行删除
这个就是对数据进行遍历,之后使用iterator.remove()移除符合条件的数据,也是目前使用最为广泛的一种操作。可以参考上文的iterator遍历,这里就不多说了。
2.新建一个List,收集所有需要删除的数据,然后进行移除全部。
List<String> deleteList= new ArrayList<>();
for (String str:list) {
if(str.equals("...")){
deleteList.add(str);
}
}
list.removeAll(deleteList);
3.新建一个list进行遍历,原本的list 进行删除。
List<String> list = new ArrayList<>();
list.add("aa");
list.add("bb");
list.add("cc");
list.add("dd");
list.add("ac");
List<String> copyList= new ArrayList<>();
copyList.addAll(list);
for (int i = copyList.size()-1; i >=0 ; i--) {
String s = copyList.get(i);
if(s.equals("...")){
list.remove(i);
}
}
4.使用Lamada
List<String> newList = list.stream().filter(s -> (!s.equals("..."))).collect(Collectors.toList());
还有就是大家注意,移除空数据不能直接
list.removeAll(null);
会出事的哦,看下图:
removeAll是不允许入参为空的,这样写就没问题了哦:
list.removeAll(Collections.singleton(null));
三、新增/插入
新增的话最长用的是add(),但是有时候也需要进行插入。不过这个不是太难,简单的提一下。
1.List尾部新增,list.add();
2.List增加集合,list.addAll();
3.List首部新增,list.add(0,str);
4.list插入多个位置多条数据,这种的话需要遍历,插入的时候List的大小又是在变化的,所以第一要克隆一个list进行遍历,原来的list进行操作添加,第二就是遍历的时候倒序遍历,这样能保证i的值始终是和原本的list一致,因为倒序插入对i前面的数值是没有影响的
四、List与Array
大家知道,List的底层就是Array,List 长度不固定的原因只是List根据需要进行动态的扩展。平时我们在码代码 时候,许多地方会牵涉到List与Array的转换,这里也简单提一下。
1.list转array
战略两步走~
String[] strArray = new String[list.size()];
String[] array = list.toArray(strArray);
2.array转list
List<String> strings = Arrays.asList(array);
3.排序问题
Array:
Arrays.sort(array);
List:
Collections.sort(list);
//或
list.sort(String::compareTo); //按照字节码排序
这个排序实现了一个compareTo方法,程序员可以根据自己的需要进行定制,然后进行排序,下面两个方法也比较常用
Collections.shuffle(list); //打乱
Collections.reverse(list); //倒序
List(主要是ArrayList)常用的大概也就这些了,有问题的话可以再一起探讨~