List集合與Set集合的區別(面試題)


一般來說,如果被別人問到一個問題:誰和誰的區別,在回答問題的時候,第一步應該回答的是他們之間有什么相似之處,充分變現出對技術的理解

相同點:ListSet都是Collection集合的子級接口!所以都具有Collection這個借口所定義的所有的方法,比如添加和移除元素。

不同點:List序列的,主要表現為其中的各元素在內存中是存在順序規則的;另外,List中的元素是可以重復的,即可以向同一個List集合中反復添加相同的數據;

Set散列的,主要表現為其中的各元素在內存中的位置是散列的,如果使用不同的實現類來存儲數據,最終在顯示Set集合中的所有元素時,顯示結果可能是無序的(HashSet),或根據排序規則進行排列的(TreeSet),或根據添加順序進行排列的(LinkedHashSet);(注意並不是說整個集合是,而是最后的顯示結果,看到的結果是這樣的)。所以不能直接說Set是無序的

另外,Set中的元素是不可重復的,即不可以向同一個Set集合中反復添加相同的數據,關於“是否相同”,取決於equals()的對比結果與hashCode()值的對比,如果2個對象的equals()對比為true並且hashCode()值相等,則視為“相同”!

所以,是否相同,取決於hashCode和equals方法,是先比較的hashCode再比較equals,如果hashCode相同,再比較equals,如果hashCode不同,就不比較了。

一、注意:不要用有序和無序來描述List集合和Set集合

比如Set集合,要看用的是哪個實現類:

(1)使用HashSet作為實現類,結果是無序的;

(2)使用TreeSet作為實現類,結果為12345有序的;

(3)使用LinkedHashSet實現類,結果與添加順序一致;

所以,直接說Set是無序的,這種說法是不精准的

詳細如下:

1.使用HashSet作為實現類,輸出為:[str-4, str-5, str-2, str-3, str-1],顯示結果是無序的

package cn.tedu.spring;

import java.util.HashSet;
import java.util.Set;

public class CollectionDemo {
	public static void main(String[] args) {
		Set<String> strings = new HashSet<String>();
		strings.add("str-1");
		strings.add("str-5");
		strings.add("str-3");
		strings.add("str-2");
		strings.add("str-4");
		System.out.println(strings);
		//輸出為:[str-4, str-5, str-2, str-3, str-1]
    }
}

2.使用TreeSet作為實現類,輸出為[str-1, str-2, str-3, str-4, str-5],顯示結果是有序的

package cn.tedu.spring;

import java.util.Set;
import java.util.TreeSet;

public class CollectionDemo {
	public static void main(String[] args) {
		Set<String> strings = new TreeSet<String>();
		strings.add("str-1");
		strings.add("str-5");
		strings.add("str-3");
		strings.add("str-2");
		strings.add("str-4");
		System.out.println(strings);
		//輸出為:[str-1, str-2, str-3, str-4, str-5]
    }
}

3.使用 LinkedHashSet作為實現類,輸出為:[str-1, str-5, str-3, str-2, str-4],和添加的順序一致,顯示結果是有序的

package cn.tedu.spring;

import java.util.LinkedHashSet;
import java.util.Set;

public class CollectionDemo {
	public static void main(String[] args) {
		Set<String> strings = new LinkedHashSet<String>();
		strings.add("str-1");
		strings.add("str-5");
		strings.add("str-3");
		strings.add("str-2");
		strings.add("str-4");
		System.out.println(strings);
		//輸出為:[str-1, str-5, str-3, str-2, str-4]
    }
}        

所以,直接說Set是無序的,這種說法是不精准的

而對於Set中的元素是不可重復的:

演示代碼:

package cn.tedu.spring;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class CollectionDemo {

	public static void main(String[] args) {
		Set<String> strings = new LinkedHashSet<String>();
		strings.add("str-1");
		strings.add("str-5");
		strings.add("str-3");
		strings.add("str-2");
		strings.add("str-2");
		strings.add("str-2");
		strings.add("str-2");
		strings.add("str-2");
		strings.add("str-4");
		System.out.println(strings);
		
        //重點關注Set集合能不能重復,是哪個實現類不重要
		Set<Student> students = new HashSet<Student>();
		students.add(new Student("Mike", 18));
		students.add(new Student("Frank", 20));
		students.add(new Student("Frank", 20));
        //這行代碼是復制上一行的
        //這個相同的student,是可以加入進去的,但絕對不是因為是new出來的這個原因
        
		students.add(new Student("Frank", 25));
		students.add(new Student("Joe", 25));
        //為了不一橫排輸出,寫一個遍歷好看些
		for (Student student : students) {
			System.out.println(student);
		}
	}

}

class Student {
	public String name;
	public int age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
    
    //下面的兩個重寫方法,都是用Source來生成的,一鍵生成
    //而開發工具不同,可能生成的代碼是不同的
    //生成的這兩個方法,目的是為了加入的屬性值的內容相同,即使是new出來的對象,也看做同一個數據,也不能加入集合
    
    //各個屬性,比如name和age的值相同,它的hashcode就一定相同,equals的對比結果也一定是true
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		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 (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
    //下面這個是自動生成的
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

如何輸出Set集合中的單個元素?

一般Set集合,就是遍歷輸出,挨個輸出里面的所有元素,

只有一種情況是輸出Set中的單個元素,就是確定這Set的實現類是LinkedHashSet,因為Linked的元素存儲結構是一個鏈一個的,所以在LinkedHashSet里面的數據其實是有下標的,或者說是有索引位置的,所以只有這種Set我們才會在當中獲取第3個元素或第5個元素。如果是一般的HashSet或TreeSet我們根本就不考慮要獲取其中的某一個。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM