知识点巩固
首先明确两个点
ArraryList
ArrayList虽然是有序的但它是按照存入顺序进行保存,并不是我们所想的排序;
ArrayList<Integer> list = new ArrayList();
list.add(23);
list.add(12);
list.add(24);
list.add(22);
list.add(22);
list.add(22);
list.add(45);
list.add(3);
从代码中我们可知我在list中放入的元素是一些int数字,而且是随机大小存入的,那么我们使用debug来看看他的内部情况
结论:ArrayList所谓的有序性是指我们放入元素的顺序,而非按照元素的大小进行排序保存,并且不会对元素进行去重,也就是说ArrayList保存元素具有重复性;
HashSet
HashSet存入元素虽然无序但是它有去重的特性;
HashSet<Integer> set = new HashSet<>();
set.add(23);
set.add(12);
set.add(24);
set.add(22);
set.add(22);
set.add(22);
set.add(45);
set.add(3);
我在HashSet中放入了一些数字,并且有3个22,依旧使用debug查看它的内部元素情况;
结论:HashSet存入元素是没有任何顺序的,既不会按照你放入的顺序也不会按照元素的大小进行排序,所以说明HashSet有无序性,但是注意HashSet存入的元素中,22只出现了一次,说明HashSet不能保存重复的元素,即HashSet保存元素具有唯一性、去重性;
测试数据
以下皆使用该数据进行测试
ArrayList<Integer> list = new ArrayList();
list.add(7);
list.add(5);
list.add(9);
list.add(8);
list.add(8);
list.add(8);
list.add(2);
list.add(3);
去重
回顾了ArrayList和HashSet,我们就可以根据他们的特性对ArrayList进行相关的操作,首先是对ArrayList进行去重
注意 以下方法在对对象进行去重时必须重写pojo类的equals(),否则HashSet会认为你内容完全相同的两个对象不相等
方式一
利用HashSet唯一性的特点对ArrayList进行去重
HashSet<Integer> set = new HashSet<>(list);
list = new ArrayList<>(set);
使用HashSet去重后会影响元素原有的位置,可以替换为LinkedHashSet保持元素原来的顺序
方式二
利用另一个临时的ArrayList配合contains()方法去重
ArrayList<Integer> temp = new ArrayList<>();
for (Integer i : list)
if (!temp.contains(i))
temp.add(i);
list = temp;
方式三
利用indexOf()和lastIndexOf()获取元素第一次和最后一次出现的位置,若位置相同则说明元素只有一个,若不相同则说明有重复该元素
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
Integer i = iterator.next();
// 如果i第一次出现的位置和最后一次出现的位置不相同则说明有重复的i
if (list.indexOf(i) != list.lastIndexOf(i))
iterator.remove();
}
此方法使用迭代器,如果该元素有重复则将该元素从迭代器中移除
方式四
利用Stream的distinct()对list去重(JDK 1.8)
List<Integer> list = this.list.stream().distinct().collect(Collectors.toList());
其他
可以使用一些集合内的方法,比如addAll(),其实和以上方法的原理大同小异
ArrayList<Integer> newList = new ArrayList<>();
HashSet<Integer> set = new HashSet<>();
set.addAll(list);
newList.addAll(set);
排序
对数字类型的排序
使用sort()方法,以匿名内部类方式传入一个比较器,重写compare()方法
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 正序排序
return o1 - o2;
// 倒序排序
// return o2 - o1;
}
});
对对象类型的排序
以下皆使用该数据进行测试
定义一个Person对象,有int id、String name、int age三个属性(使用了Lombok工具)
@Data
@AllArgsConstructor
public class Person{
private int id;
private String name;
private int age;
}
测试用对象数据
ArrayList<Person> list = new ArrayList<>();
list.add(new Person(4,"Jack",22));
list.add(new Person(7,"Maria",20));
list.add(new Person(5,"Lucy",24));
list.add(new Person(2,"Alix",24));
list.add(new Person(9,"Rote",25));
排序前遍历元素
Person(id=4, name=Jack, age=22)
Person(id=7, name=Maria, age=20)
Person(id=5, name=Lucy, age=24)
Person(id=2, name=Alix, age=24)
Person(id=9, name=Rote, age=25)
Comparable
使用Comparable的前提是,pojo类必须实现Comparable接口
@Data
@AllArgsConstructor
public class Person implements Comparable<Person>{
private int id;
private String name;
private int age;
@Override
public int compareTo(Person p) {
// 按照String属性排序
// 正序排序
return this.getName().compareTo(p.getName());
// 倒序排序
// return p.getName().compareTo(this.getName());
}
}
然后使用Collections.sort()方法对list进行排序,sort()会自动匹配Person实现的比较器(Comparable),根据比较器内的规则对Pserson实例进行排序
Collections.sort(list); // 使用Collections的sort()方法
遍历输出(按照name进行排序)
Person(id=5, name=Alix, age=24)
Person(id=4, name=Jack, age=22)
Person(id=2, name=Lucy, age=24)
Person(id=7, name=Maria, age=20)
Person(id=9, name=Rote, age=25)
Collections.sort(list)以定义的实现规则按照name对Person对象进行正序排序(A-Z)
Comparator
Comparator比Comparable更简单,可以使用匿名内部类进行实现,并且可以进行复杂逻辑的规则实现,能够按照更多的条件进行排序
// 直接使用list的sort()方法,用匿名内部类方式实现Comparator
list.sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
// 优先按照age排序
if (o1.getAge() != o2.getAge() ) { // 若两个person的age不相等则按age正序排序
return o1.getAge() - o2.getAge();
} else { // 若age相同则按照name正序排序
return o1.getName().compareTo(o2.getName());
}
}
});
遍历输出
Person(id=7, name=Maria, age=20)
Person(id=4, name=Jack, age=22)
Person(id=2, name=Alix, age=24)
Person(id=5, name=Lucy, age=24)
Person(id=9, name=Rote, age=25)
sort()先按照age进行了正确的正序排列,当遇到两个相同的age=24时,它又对name进行了判定,让原本在Lucy后面的Alix排在了前面
后言
你好,很高兴认识你
本次关于 “ 如何对ArrayList进行去重、排序 ” 的文章到此完结,其实除了这些主要的方式,还有很多其他方法可以进行实现,若有疑问可以私信与我交流。
如果你也喜欢编程,如果你也喜欢敲代码,如果你也喜欢技术,欢迎联系~
我是
爱敲代码的小王bro