一.为什么要去重?,去重原理
1.为什么要进行去重
在使用集合框架时,我们经常需要对一个集合中的元素进行去重操作。去重操作可以使集合中不同的元素呈现出来,去掉重复元素,从而降低程序开销和提高计算效率。在实际项目中,我们可能会遇到需要对一些大数据量的集合进行去重操作,如果不进行去重操作,可能会严重影响程序的性能和运行效率。
对于ArrayList集合来说,虽然其允许存储重复元素,但是在某些业务场景下,我们需要保证元素不重复。因此,当我们需要对ArrayList集合中的元素进行去重时,就需要进行底层的去重操作。
在底层去重操作中,我们可以使用集合框架提供的HashSet类对ArrayList中的元素进行去重。它的底层实现是基于哈希表的,当我们将ArrayList中的元素添加到HashSet中时,HashSet会自动去重元素,从而实现ArrayList集合的去重。使用HashSet对ArrayList进行底层去重操作不仅性能高效,而且代码简洁。
在进行去重时我们还可以通过equals方法方法的返回值来进行操作,并且因此来去除集合中的重复元素,当然小编还是更推荐使用HashSet对ArrayList进行元素去重!
除此之外,在集合中进行去重操作还可以帮助提高程序的质量和可维护性。当我们需要基于某个字段进行去重操作时,我们可以将该字段作为元素的属性,并在equals和hashCode方法中使用该属性进行比较,这样可以提高程序的可读性和可维护性。
2.去重原理
在ArrayList中,如果我们需要对元素进行去重,需要注意元素类型是否正确重写了hashCode和equals方法。根据集合框架中的规定,如果两个元素的equals方法返回true,则它们的hashCode值必须相等。因此,正确重写equals方法是确保元素能够正确去重的关键。
在Java中,equals方法是用来比较两个对象是否相等的方法。当我们需要比较自定义对象时,需要重写equals方法,以便让其能够正确地比较两个对象是否相等。通常我们只需要重写equals方法,而不需要重写hashCode方法,因为在使用集合框架时,hashCode方法一般会被自动调用。
在重写equals方法时,我们需要遵循以下几个原则:
1. 自反性:对于任何非空引用x,x.equals(x)应该返回true。
2. 对称性:对于任何非空引用x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true。
3. 传递性:对于任何非空引用x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,则x.equals(z)也应该返回true。
4. 一致性:对于任何非空引用x和y,连续多次调用x.equals(y)应该返回相同的结果。
5. 非空性:对于任何非空引用x,x.equals(null)应该返回false。
对于ArrayList来说,在去重时会先调用元素的equals方法判断两个元素是否相等,如果equals方法返回true,则判断这两个元素是重复的,只保留其中的一个副本。如果equals方法返回false,则认为这两个元素是不同的,不会进行去重操作。
需要注意的是,当我们使用ArrayList进行去重时,元素的equals方法的实现方式对去重结果有很大的影响。因此,在实现自定义对象的equals方法时,我们需要基于具体的业务场景来实现,以确保元素能够正确地去重。
二.实例
1.字符串去重
1.1代码截屏:
1.2代码效果图
1.3源码:
package com.lz.list; import java.util.ArrayList; import java.util.List; public class demo4 { public static void main(String[] args) { /** * 字符串去重 */ List list = new ArrayList<>(); list.add("q"); list.add("f"); list.add("h"); System.out.println("当前原素:" + list); if (!list.contains("h")) { list.add("h"); } System.out.println("现在原素:" + list); } }
2.对象去重
2.1代码截屏:
2.2代码效果图:
2.3源码:
package com.lz.list; import java.util.ArrayList; import java.util.List; public class demo7 { public static void main(String[] args) { /** * 对象去重 */ List list = new ArrayList<>(); list.add(new stu("多久哦")); list.add(new stu("山东积分")); list.add(new stu("速度放缓")); System.out.println("当前原素:" + list); if (!list.contains(new stu("多久哦"))) { list.add(new stu("多久哦")); } System.out.println("现在原素:" + list); } } //创建一个对象 class stu{ private String name; public stu() { // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see java.lang.Object#toString() */ //调用get set方法 @Override public String toString() { return "stu [name=" + name + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public stu(String name) { super(); this.name = name; } //创建 equals方法 @Override public boolean equals(Object obj) { //为什么 会这样原因是 equals方法返回值相关 System.out.println("送积分"); if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; stu other = (stu) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }