歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java HashSet的元素內容變化導致的問題

Java HashSet的元素內容變化導致的問題

日期:2017/3/1 9:19:53   编辑:Linux編程

概述

HashSet元素引用的對象的內容發生變化,會導致“元素不屬於集合”的問題。事實上這個元素還在集合裡,但是調用contains方法進行判斷,得到的結果卻是false。

正文

關於變化

這裡所講的變化是指元素引用的對象的內容的變化,但是對象還是這個對象。比如我們定義如下的field

private Set<Set<Integer>> cache = new HashSet<Set<Integer>>();

我們計劃cache裡的每一個元素都是一個Set<Integer>的集合。如果我們取出cache的一個元素,然後往這個元素集合中添加一個Integer元素。對於cache來說,這個元素還是這個元素,但是它的內容已經變化了。

關於校驗標准

/**
* 校驗.<br>
* 從集合中取出的元素反而不屬於該集合,則為無效.
* @return
*/
private boolean validate() {
boolean flag = true;
for ( Set<Integer> ele : cache ) {
if (!cache.contains(ele)) {
flag = false;
System.out.println("無效的元素:" + ele);
}
}

return flag;
}

測試

我們分為三個測試用例:數據初始化測試、直接更新測試、移除新增測試。

一、數據初始化測試

1. 數據初始化

/**
* 初始化數據.
*/
private void init() {
Integer[][] data = {{1, 2}, {3, 4}, {5}};
for (Integer[] ele : data) {
List<Integer> eleList = Arrays.asList(ele);
Set<Integer> eleSet = new HashSet<Integer>(eleList.size());
eleSet.addAll(eleList);

cache.add(eleSet);
}

System.out.println(cache);
}

2. 測試

@Test
public void testInit() {
init();
boolean flag = validate();
System.out.println("對初始化的數據進行校驗,結果:" + flag);
}

3. 輸出結果

[[2, 1], [5], [4, 3]]
對初始化的數據進行校驗,結果:true

二、直接更新測試

1. 更新的方法

/**
* 直接修改.
*/
private void update() {
for (Set<Integer> ele : cache) {
if (ele.contains(5)) {
ele.add(6);
break;
}
}

System.out.println(cache);
}

2. 測試

@Test
public void testUpdate() {
init();
update();

boolean flag = validate();
System.out.println("對直接修改的數據進行校驗,結果:" + flag);
}

3. 輸出結果

[[2, 1], [5], [4, 3]]
[[2, 1], [6, 5], [4, 3]]
無效的元素:[6, 5]
對直接修改的數據進行校驗,結果:false

三、移除新增測試

1. 移除新增

/**
* 移除添加.
*/
private void removeThenAdd() {
for (Set<Integer> ele : cache) {
if (ele.contains(5)) {
cache.remove(ele);
ele.add(6);
cache.add(ele);
break;
}
}

System.out.println(cache);
}

2. 測試

@Test
public void testRA() {
init();
removeThenAdd();

boolean flag = validate();
System.out.println("對移除添加的數據進行校驗,結果:" + flag);
}

3. 輸出結果

[[2, 1], [5], [4, 3]]
[[2, 1], [4, 3], [6, 5]]
對移除添加的數據進行校驗,結果:true

結論

我認為HashSet遍歷元素和判斷元素是否在集合中的機制是不同的,HashSet中的元素都有一個不同的hashcode,我們直接修改其中的元素,導致其內容和其hashcode對應不上,所以才會有上述的問題。

Copyright © Linux教程網 All Rights Reserved