知识点巩固

首先明确两个点

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重新排序_ide

结论: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查看它的内部元素情况;

arraylist更新某一索引的数据 arraylist重新排序_ide_02

 结论: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