Java中的List是可以包含重复元素的(hash code 和equals),接下来将介绍两种方式实现java list去重操作,感兴趣的朋友可以参考下
 
Java中的List是可以包含重复元素的(hash code 和equals),那么对List进行去重操作有两种方式实现:
方案一:可以通过HashSet来实现,代码如下:

复制代码 代码如下:
class Student {
private String id;
private String name;
public Student(String id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Student other = (Student) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
}

必须实现hashCode和equals两个方法,一会我们会看为啥必须实现
具体的操作代码如下:

复制代码 代码如下:
private static void removeListDuplicateObject() {
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < 10; i++) {
Student student = new Student("id", "name");
list.add(student);
}
System.out.println(Arrays.toString(list.toArray()));
Set<Student> set = new HashSet<Student>();
set.addAll(list);
System.out.println(Arrays.toString(set.toArray()));
list.removeAll(list);
set.removeAll(set);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(set.toArray()));
}

调用代码:

复制代码 代码如下:
public static void main(String[] args) {
removeListDuplicateObject();
}

利用HashSet进行去重操作,为啥必须覆盖hashCode和equals两个方法呢?
我们查看HashSet的add操作源码如下:

复制代码 代码如下:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

调用了HashMap进行操作的,我们看HashMap的put操作:

复制代码 代码如下:
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}

需要注意的是:

复制代码 代码如下:
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
......
}

也就是说hash code相等且equals(==)。
复杂度:一边遍历即可,O(n)
方案二:直接遍历一遍List进行通过contains和add操作实现
代码如下:

复制代码 代码如下:
private static void removeListDuplicateObjectByList() {
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < 10; i++) {
Student student = new Student("id", "name");
list.add(student);
}
System.out.println(Arrays.toString(list.toArray()));
List<Student> listUniq = new ArrayList<Student>();
for (Student student : list) {
if (!listUniq.contains(student)) {
listUniq.add(student);
}
}
System.out.println(Arrays.toString(listUniq.toArray()));
list.removeAll(list);
listUniq.removeAll(listUniq);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(listUniq.toArray()));
}

其他等同上面。
复杂度:
一边遍历,同时调用了contains方法,我们查看源码如下:

复制代码 代码如下:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

可以看到又对新的list做了一次遍历操作。也就是1+2+....+n这样复杂度为O(n*n)
结论:
方案一效率高,即采用HashSet的方式进行去重操作

 

java list去重操作实现方式的更多相关文章

  1. Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式

    解析:Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式.面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和Out ...

  2. java list去重方式,以及效率问题

    之前面试被问到关于java如何去重的问题,当时没怎么留意,今天刚好项目中用到了,所以记录一下. 实体类: /** * 用户类 */ class User{ private String usernam ...

  3. Phoenix简介概述,Phoenix的Java API 相关操作优秀案例

    Phoenix简介概述,Phoenix的Java API 相关操作优秀案例 一.Phoenix概述简介 二.Phoenix实例一:Java API操作 2.1 phoenix.properties 2 ...

  4. 深度掌握 Java Stream 流操作,让你的代码高出一个逼格!

    概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream 的操作符大体上分为两种:中间操作符和终止操作符 中 ...

  5. 全面吃透JAVA Stream流操作,让代码更加的优雅

    全面吃透JAVA Stream流操作,让代码更加的优雅 在JAVA中,涉及到对数组.Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行 ...

  6. Java Spring mvc 操作 Redis 及 Redis 集群

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...

  7. Java的JDBC操作

    Java的JDBC操作 [TOC] 1.JDBC入门 1.1.什么是JDBC JDBC从物理结构上来说就是java语言访问数据库的一套接口集合,本质上是java语言根数据库之间的协议.JDBC提供一组 ...

  8. Java生成和操作Excel文件(转载)

    Java生成和操作Excel文件   JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该A ...

  9. Java序列化的几种方式以及序列化的作用

    Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象 ...

随机推荐

  1. 51nod 1489 蜥蜴和地下室(dp)

    传送门 题意 分析 dp[12][20][20][20]; // dp[a][b][c][d]第a个弓箭手面临第a-1.a.a+1个弓箭手的生命值分别为b.c.d的状态 转移巧妙,需注意 trick ...

  2. IT兄弟连 Java Web教程 经典案例2

    案例需求:写一个用户登录的html页面有账号和密码,并在登录的Servlet中获取登录的账号和密码,如果账号是abc密码是123则向浏览器输出登录成功,否则向浏览器输出登录失败. 案例实现: ●  h ...

  3. noip 2012 Day2 T2 借教室

    一.暴力简述 甩链接.jpeg 首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减 ...

  4. Ubuntu 设置文件默认打开的应用

    右键单击该文件,然后点击属性,打开属性面板 然后进入open with的选项,选择应用后,点击 set as default

  5. ngxin做http强制跳转https,接口的POST请求变成GET

    http强制跳转https出现了问题.修改nginx配置如下即可解决: server { listen 80; server_name *.snsprj.cn; return 307 https:// ...

  6. Failed to convert property value of type 'java.util.LinkedHashMap' to required type 'java.util.Map' for property 'filters'

    在使用shiro的自定义filter出现的问题 <property name="filters"> <util:map> <entry key=&qu ...

  7. 洛谷 P3312 [SDOI2014]数表

    式子化出来是$\sum_{T=1}^m{\lfloor}\frac{n}{T}{\rfloor}{\lfloor}\frac{m}{T}{\rfloor}\sum_{k|T}\mu(\frac{T}{ ...

  8. 洛谷 P4317 花神的数论题 || bzoj3209

    https://www.lydsy.com/JudgeOnline/problem.php?id=3209 https://www.luogu.org/problemnew/show/P4317 设c ...

  9. N Queen Again LightOJ - 1061

    N Queen Again LightOJ - 1061 首先预处理(或打表)出所有八皇后的解法(只有92种).然后枚举目标状态,对于每一个目标状态用一个状压dp求出到达那个状态的最小费用.到达任何一 ...

  10. python正则表达式提取中文

    import urllib.requestimport reurl='https://songsearch.kugou.com/song_search_v2?callback=jQuery112407 ...