以List为例:
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("a");
list.add("b");
list.add("c");
1、最容易想到的就是两层for循环
for(int i = 0; i < list.size(); i++) {
for(int j = 0; j < list.size(); j++) {
if(list.get(i).equals(list.get(j))) {
list.remove(j);
}
}
}
这样想没错,但是这样写不对,这样会把重复的值都删除,我们要保留一个重复的值,这里保留第一个,所以二层循环要从一层循环之后开始:
for(int i = 0; i < list.size(); i++) {
for(int j = i + 1; j < list.size(); j++) {
if(list.get(i).equals(list.get(j))) {
list.remove(j);
}
}
}
这样list结果为[a, b, c, d, e]
但是当list:
List<String> list = new ArrayList<>();
list.add("a");// 0
list.add("b");// 1
list.add("c");// 2
list.add("d");// 3
list.add("e");// 4
list.add("a");// 5 a1
list.add("a");// 6 a2
list.add("b");// 7 b1
list.add("c");// 8
结果就是 [a, b, c, d, e, a]
因为当 i=0 j=5时,会把a1删除,这时a2前进一位角标变成a1的5了,而下一次循环时j=6,这时角标6的值是b1,所以a2就被跳过了判断:
list.add("a");// 0
list.add("b");// 1
list.add("c");// 2
list.add("d");// 3
list.add("e");// 4
list.add("a");// 5 a2
list.add("b");// 6 b1
list.add("c");// 7
采用倒叙遍历可以规避这个问题,两层for循环最终代码:
for (int i = 0; i < list.size(); i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(i).equals(list.get(j))) {
list.remove(j);
}
}
}
2、利用List的contains方法
List<String> newList = new ArrayList<>();
for(String s : list) {
if (!newList.contains(s)) {
newList.add(s);
}
}
3、利用HashSet元素不重复的特性
Set<String> set = new HashSet<>(list);
// 如果想得到结果为list:
list = new ArrayList<>(new HashSet<>(list));
4、利用Java8的流操作
list = list.stream().distinct().collect(Collectors.toList());
以上是比较通用的方法,假如集合中重复的值最多只有2个的话,可以用indexOf和lastIndexOf,如果重复的值大于2个删不干净。
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
int indexOf = list.indexOf(next);
int lastIndexOf = list.lastIndexOf(next);
if (indexOf != lastIndexOf) {
iterator.remove();
}
}
注意: 有的同学在写的时候可能觉得增强for写法简单,这里绝对不能用,因为删除一个值,list.size()就变了,增强for循环会报错。
如果还有好的想法,欢迎留言交流。