欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java list去重操作實(shí)現(xiàn)方式

 更新時(shí)間:2012年12月05日 15:57:46   作者:  
Java中的List是可以包含重復(fù)元素的(hash code 和equals),接下來將介紹兩種方式實(shí)現(xiàn)java list去重操作,感興趣的朋友可以參考下
Java中的List是可以包含重復(fù)元素的(hash code 和equals),那么對(duì)List進(jìn)行去重操作有兩種方式實(shí)現(xiàn):
方案一:可以通過HashSet來實(shí)現(xiàn),代碼如下:
復(fù)制代碼 代碼如下:

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;
}
}

必須實(shí)現(xiàn)hashCode和equals兩個(gè)方法,一會(huì)我們會(huì)看為啥必須實(shí)現(xiàn)
具體的操作代碼如下:
復(fù)制代碼 代碼如下:

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()));
}

調(diào)用代碼:
復(fù)制代碼 代碼如下:

public static void main(String[] args) {
removeListDuplicateObject();
}

利用HashSet進(jìn)行去重操作,為啥必須覆蓋hashCode和equals兩個(gè)方法呢?
我們查看HashSet的add操作源碼如下:
復(fù)制代碼 代碼如下:

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

調(diào)用了HashMap進(jìn)行操作的,我們看HashMap的put操作:
復(fù)制代碼 代碼如下:

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;
}

需要注意的是:
復(fù)制代碼 代碼如下:

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
......
}

也就是說hash code相等且equals(==)。
復(fù)雜度:一邊遍歷即可,O(n)
方案二:直接遍歷一遍L(zhǎng)ist進(jìn)行通過contains和add操作實(shí)現(xiàn)
代碼如下:
復(fù)制代碼 代碼如下:

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()));
}

其他等同上面。
復(fù)雜度:
一邊遍歷,同時(shí)調(diào)用了contains方法,我們查看源碼如下:
復(fù)制代碼 代碼如下:

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;
}

可以看到又對(duì)新的list做了一次遍歷操作。也就是1+2+....+n這樣復(fù)雜度為O(n*n)
結(jié)論:
方案一效率高,即采用HashSet的方式進(jìn)行去重操作

相關(guān)文章

  • Java 同步鎖(synchronized)詳解及實(shí)例

    Java 同步鎖(synchronized)詳解及實(shí)例

    這篇文章主要介紹了Java 同步鎖(synchronized)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • MybatisPlus #{param}和${param}的用法詳解

    MybatisPlus #{param}和${param}的用法詳解

    這篇文章主要介紹了MybatisPlus #{param}和${param}的用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java線程協(xié)作的兩種方式小結(jié)

    Java線程協(xié)作的兩種方式小結(jié)

    Java中線程協(xié)作的最常見的兩種方式是利用Object.wait()、Object.notify()和使用Condition,本文主要介紹了Java線程協(xié)作的兩種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 詳解JAVA 時(shí)間處理相關(guān)類

    詳解JAVA 時(shí)間處理相關(guān)類

    這篇文章主要介紹了JAVA 時(shí)間處理相關(guān)類的知識(shí),文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java枚舉類型enum的詳解及使用

    Java枚舉類型enum的詳解及使用

    這篇文章主要介紹了Java枚舉類型enum的詳解及使用的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java中extends一定是代表繼承嗎?

    Java中extends一定是代表繼承嗎?

    今天小編就為大家分享一篇關(guān)于Java中extends一定是代表繼承嗎?,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java設(shè)計(jì)模式編程中簡(jiǎn)單工廠與抽象工廠模式的使用實(shí)例

    Java設(shè)計(jì)模式編程中簡(jiǎn)單工廠與抽象工廠模式的使用實(shí)例

    這篇文章主要介紹了Java設(shè)計(jì)模式編程中簡(jiǎn)單工廠與抽象工廠模式的使用實(shí)例,簡(jiǎn)單工廠與抽象工廠都可以歸類于設(shè)計(jì)模式中的創(chuàng)建型模式,需要的朋友可以參考下
    2016-04-04
  • java動(dòng)態(tài)規(guī)劃算法——硬幣找零問題實(shí)例分析

    java動(dòng)態(tài)規(guī)劃算法——硬幣找零問題實(shí)例分析

    這篇文章主要介紹了java動(dòng)態(tài)規(guī)劃算法——硬幣找零問題,結(jié)合實(shí)例形式分析了java動(dòng)態(tài)規(guī)劃算法——硬幣找零問題相關(guān)原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-05-05
  • mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)

    mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié)

    MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架。接下來通過本文給大家介紹mybatis快速入門學(xué)習(xí)教程新手注意問題小結(jié),需要的朋友可以參考下
    2017-02-02
  • Java利用ffmpeg實(shí)現(xiàn)視頻MP4轉(zhuǎn)m3u8

    Java利用ffmpeg實(shí)現(xiàn)視頻MP4轉(zhuǎn)m3u8

    本文綜合了下網(wǎng)上教程,從ffmpeg工具轉(zhuǎn)碼,ffmpeg視頻播放,java語(yǔ)言操控ffmpeg轉(zhuǎn)碼,轉(zhuǎn)碼后視頻上傳阿里云oss,四個(gè)方面完整記錄下這個(gè)流程,需要的朋友可以參考下
    2024-02-02

最新評(píng)論