前言
数据去重是项目中经常出现的应用场景,并且面试中可能也会问到,那么你会几种数组去重方式呢?
实战
使用额外空间去重
List<String> list = Arrays.asList("java", "html", "js", "sql", "java");
@Test
public void test8() {
List<String> newList = new ArrayList<>();
for (String el : list) {
if(!newList.contains(el)) {
newList.add(el);
}
}
System.out.println(newList);
}
优点:实现简单、并且在循环判断过程中可以增加额外操作
缺点:需要一个额外空间大小的数组,浪费空间,多行代码实现
Set集合自动去重
List<String> list = Arrays.asList("java", "html", "js", "sql", "java");
@Test
public void test8() {
Set<String> set = new HashSet<>(list);
List<String> newList = new ArrayList<>(set);
System.out.println(newList);
}
优点:利用
Set
集合的不重复特性去重更简单缺点:使用额外空间,需要来回转换,不太优雅
Java8一键去重(distinct)
List<String> list2 = Arrays.asList("java", "html", "js", "sql", "java");
@Test
public void test9() {
// java8 stream-api去重
list2.stream()
.distinct()
.forEach(System.out::println);
}
优点:java8新特性,流式操作简单方便(和sql一样),代码优雅
缺点:无法在去重的过程中进行额外操作
distinct去重注意事项
既然这么好用,那distinct是通过什么去重的呢?如果是引用类型,是通过地址去重还是通过某些字段去重呢?
-
distinct去重失效示例代码
List<Employee> list = Arrays.asList(
new Employee( "小明", 18),
new Employee( "赵六", 38),
new Employee( "张三", 6),
new Employee( "小明", 18)
);
class Employee {
private String name;
private Integer age;
public Employee(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
@Test
public void test9() {
list.stream()
.distinct()
.forEach(System.out::println);
}控制台输出:
Employee{name='小明', age=18}
Employee{name='赵六', age=38}
Employee{name='张三', age=6}
Employee{name='小明', age=18}结果:使用自定义对象
distinct
无法去重,难道distinct
无法作用引用类型吗?但是刚才的String
也是引用类型,但是也可以去重。自定义的对象Employee
和String
有什么区别吗?没错,就是hashcode()
和equals()
方法,String
已经重写了这两个方法,自定义的Employee
没有重写这两个方法。注意:只要是涉及
Map
和Set
这种去重的集合,或者Java8的distinct
去重,都是通过hashcode()
和equals
来作为数据去重的依据,所以要注意重写这两个方法 -
修改测试
class Employee {
private String name;
private Integer age;
...
// 重写equals和hashcode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) &&
Objects.equals(age, employee.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
...
}
@Test
public void test9() {
list.stream()
.distinct()
.forEach(System.out::println);
}控制台输出:
Employee{name='小明', age=18}
Employee{name='赵六', age=38}
Employee{name='张三', age=6}重写
hashcode
和equals
可以实现去重。
小总结
无论使用Set
集合去重还是使用Java8的新特性stream流的distinct
去重,都是通过hashcode()
和equals()
自定义的策略进行去重。
原文始发于微信公众号(指尖上的代码):数组去重,你会几种方式?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/40001.html