A. java中 List 與Set 有什麼區別
Java的集合類都位於java.util包中,Java集合中存放的是對象的引用,而非對象本身。
Java集合主要分為三種類型:
a.Set(集):集合中的對象不按特定方式排序,並且沒有重復對象。它的有些實現類能對集合中的對象按特定方式排序。
b.List(列表):集合中的對象按索引位置排序,可以有重復對象,允許按照對象在集合中的索引位置檢索對象。
c.Map(映射):集合中的每一個元素包含一對鍵對象和值對象,集合中沒有重復的鍵對象,值對象可以重復。它的有些實現類能對集合中的鍵對象進行排序。
Set、List和Map統稱為Java集合。
1.Set(集)
Set集合中的對象不按特定方式排序,並且沒有重復對象。Set介面主要有兩個實現類HashSet和TreeSet。HashSet類按照哈希演算法來存取集合中的對象,存取速度比較快。HashSet類還有一個子類LinkedHashSet類,它不僅實現了哈希演算法,而且實現了鏈表數據結構。TreeSet類實現了SortedSet介面,具有排序功能。
Set的add()方法判斷對象是否已經存在於集合中的判斷流程:
boolean isExists = false;
Iterator it = set.iterator();
while(it.hasNext()){
Object object = it.next();
if(newObject.equals(oldObject)){
isExists = true;
break;
}
}
2.HashSet類
當HashSet向集合中加入一個對象時,會調用對象的hashCode()方法獲得哈希碼,然後根據這個哈希碼進一步計算出對象在集合中的存放位置。
當Object1變數和object2變數實際上引用了同一個對象,那麼object1和object2的哈希碼肯定相同。
為了保證HashSet能正常工作,要求當兩個對象用equals()方法比較的結果為相等時,它們的哈希碼也相等。即:
customer1.hashCode() == customer2.hashCode();
如:對應於Customer類的以下重寫後的equals()方法:
public boolean equals(Object o){
if(this==o) return true;
if(!o instanceof Customer) return false;
final Customer other = (Customer)o;
if(this.name.equals(other.getName())&&this.age==other.getAge())
return true;
else
return false;
}
為了保證HashSet正常工作,如果Customer類覆蓋了equals()方法,也應該覆蓋hashCode()方法,並且保證兩個相等的Customer對象的哈希碼也一樣。
public int hashCode(){
int result;
result = (name==null?0:name.hashCode());
result = 29*result+(age==null?0:age.hashCode());
return result;
}
3.TreeSet類
TreeSet類實現了SortedSet介面,能夠對集合中的對象進行排序。TreeSet支持兩種排序方式:自然排序和客戶化排序,在默認情況下TreeSet採用自然排序方式。
a.自然排序
在JDK中,有一部分類實現了Comparable介面,如Integer、Double和String等。Comparable介面有一個compareTo(Object o)方法,它返回整數類型。對於表達式x.compareTo(y),如果返回值為0,表示x和y相等,如果返回值大於0,表示x大於y,如果返回值小於0,表示x小於y。
TreeSet調用對象的compareTo()方法比較集合中對象的大小,然後進行升序排列,這種排序方式稱為自然排序。
以下列出了JDK中實現了Comparable介面的一些類的排序方式
類 排序
BigDecimal\BigInteger\Byte\Double\Float\Integer\Long\Short 按數字大小排序
Character 按字元的Unicode值的數字大小排序
String 按字元串中字元的Unicode值排序
使用自然排序時,只能向TreeSet集合中加入同類型的對象,並且這些對象的類必須實現了Comparable介面,否則會在第二次調用TreeSet的add()方法時,會拋出ClassCastException異常。
例如:
以下是Customer類的compareTo()方法的一種實現方式:
public int compareTo(Object o){
Customer other = (Customer)o;
//先按照name屬性排序
if(this.name.compareTo(other.getName())>0) return 1;
if(this.name.compareTo(other.getName())<0) return -1;
//再按照age屬性排序
if(this.age>other.getAge()) return 1;
if(this.age<other.getAge()) return -1;
return 0;
}
為了保證TreeSet能正確地排序,要求Customer類的compareTo()方法與equals()方法按相同的規則比較兩個Customer對象是否相等。
因此在Customer類的equals()方法中應該採用相同的比較規則:
public boolean equals(Object o){
if(this==o) return true;
if(!(o instanceof Customer)) return false;
final Customer other = (Customer)o;
if(this.name.equals(other.getName())&&this.age==other.getAge()){
return true;
}else{
return false;
}
}
值得注意的是,對於TreeSet中已經存在的Customer對象,如果修改了它們的屬性,TreeSet不會對集合進行重新排序。在實際域模型中,實體類的屬性可以被更新,因此不適合通過TreeSet來排序。最適合於排序的是不可變類。
b.客戶化排序
除了自然排序,TreeSet還支持客戶化排序。java.util.Comparator介面用於指定具體的排序方式,它有個compare(Object object1,Object object2)方法,用於比較兩個對象的大小。當表達式compare(x,y)的值大於0,表示x大於y;當compare(x,y)的值小於0,表示x小於y;當compare(x,y)的值等於0,表示x等於y。
例如:如果希望TreeSet僅按照Customer對象的name屬性進行降序排列,可以創建一個實現Comparator介面的類CustomerComparator:
public class CustomerComparator implements Comparator{
public int compare(Object o1,Object o2){
Customer c1= (Customer)o1;
Customer c2 = (Customer)o2;
if(c1.getName().compareTo(c2.getName())>0) return -1;
if(c2.getName().compareTo(c2.getName())<0) return 1;
return 0;
}
}
接下來在構造TreeSet的實例時,調用它的TreeSet(Comparator comparator)構造方法:
Set set = new TreeSet(new CustomerComparator());
4.向Set中加入持久化類的對象
例如兩個Session實例從資料庫載入相同的Order對象,然後往HashSet集合里存放,在默認情況下,Order類的equals()方法比較兩個Orer對象的內存地址是否相同,因此order1.equals(order2)==false,所以order1和order2游離對象都加入到HashSet集合中,但實際上order1和order2對應的是ORDERS表中的同一條記錄。對於這一問題,有兩種解決方案:
(1)在應用程序中,謹慎地把來自於不同Session緩存的游離對象加入到Set集合中,如:
Set orders = new HashSet();
orders.add(order1);
if(!order2.getOrderNumber().equals(order1.getOrderNumber()))
order.add(order2);
(2)在Order類中重新實現equals()和hashCode()方法,按照業務主鍵比較兩個Order對象是否相等。
提示:為了保證HashSet正常工作,要求當一個對象加入到HashSet集合中後,它的哈希碼不會發生變化。
5.List(列表)
List的主要特徵是其對象以線性方式存儲,集合中允許存放重復對象。List介面主要的實現類有LinkedList和ArrayList。LinkedList採用鏈表數據結構,而ArrayList代表大小可變的數組。List介面還有一個實現類Vector,它的功能和ArrayList比較相似,兩者的區別在於Vector類的實現採用了同步機制,而ArrayList沒有使用同步機制。
List只能對集合中的對象按索引位置排序,如果希望對List中的對象按其他特定方式排序,可以藉助Comparator和Collections類。Collections類是集合API中的輔助類,它提供了操縱集合的各種靜態方法,其中sort()方法用於對List中的對象進行排序:
a.sort(List list):對List中的對象進行自然排序。
b.sort(List list,Comparator comparator):對List中的對象進行客戶化排序,comparator參數指定排序方式。
如Collections.sort(list);
6.Map(映射)
Map(映射)是一種把鍵對象和值對象進行映射的集合,它的每一個元素都包含一對鍵對象和值對象,而值對象仍可以是Map類型,依次類推,這樣就形成了多級映射。
Map有兩種比較常用的實現:HashMap和TreeMap。HashMap按照哈希演算法來存取鍵對象,有很好的存取性能,為了保證HashMap能正常工作,和HashSet一樣,要求當兩個鍵對象通過equals()方法比較為true時,這兩個對象的hashCode()方法返回的哈希碼也一樣。
TreeMap實現了SortedMap介面,能對鍵對象進行排序。和TreeSet一樣,TreeMap也支持自然排序和客戶化排序兩種方式。
例:創建一個緩存類EntityCache,它能粗略地模仿Session的緩存功能,保證緩存中不會出現兩個OID相同的Customer對象或兩個OID相同的Order對象,這種惟一性是由鍵對象的惟一性來保證的。
Key.java:
package mypack;
public class Key{
private Class classType;
private Long id;
public Key(Class classType,Long id){
this.classType = classType;
this.id = id;
}
public Class getClassType(){
return this.classType;
}
public Long getId(){
return this.id;
}
public boolean equals(Object o){
if(this==o) return true;
if(!(o instanceof Key)) return false;
final Key other = (Key)o;
if(classType.equals(other.getClassType())&&id.equals(other.getId()))
return true;
return false;
}
public int hashCode(){
int result;
result = classType.hashCode();
result = 29 * result + id.hashCode();
return result;
}
}
EntityCache.java:
package mypack;
import java.util.*;
public class EntityCache {
private Map entitiesByKey;
public EntityCache() {
entitiesByKey=new HashMap();
}
public void put(BusinessObject entity){
Key key=new Key(entity.getClass(),entity.getId());
entitiesByKey.put(key,entity);
}
public Object get(Class classType,Long id){
Key key=new Key(classType,id);
return entitiesByKey.get(key);
}
public Collection getAllEntities(){
return entitiesByKey.values();
}
public boolean contains(Class classType,Long id){
Key key=new Key(classType,id);
return entitiesByKey.containsKey(key);
}
}
B. java中set怎麼轉換成list
Map<String,String>map=newHashMap<String,String>();
map.put("ele1","小櫻");
map.put("ele2","若曦");
map.put("ele3","晴川");
Set<String>set=map.keySet();
//Set轉List,方法一:ArrayList(Collection<?>c)
List<String>list1=newArrayList<String>(set);
for(inti=0;i<list1.size();i++){
System.out.println("list1("+i+")-->"+list1.get(i));
}
//Set轉List,方法二:List實現類(ArrayList/LinkedList)的方法--addAll(Collection<?>c)
List<String>list2=newArrayList<String>();
list2.addAll(set);
for(Stringelem:list2){
System.out.println(elem);
}
C. java set與list
向list里加之前,先看看list里是否有和這個重復的,有的話就不加。用list.contains(Object o)判斷。不過你要復寫equals方法,滿足你的要求才行。
下面的先放set再放list是有問題的,放入set後已經亂序了,
再向set中放沒意義
D. Java中Set 和List兩個集合怎樣互相轉化
Set和List都是介面,他們的取得都必須是實現了Collection介面和Iterable介面的類。只要是實現了這兩個介面的類都就可以實現取得Set介面對象和List介面的目的。
我只用過Set,覺得他們用的地方不一樣,所以應該是不能轉換的。
真正要進行轉換的話,就應當是用實現了Collection介面和Iterable介面的集合對象去取得這兩個介面的對象吧。
E. java中list和set的區別
1、List,Set都是繼承自Collection介面
2、List特點:元素有放入順序,元素可重復 ,Set特點:元素無放入順序,元素不可重復(注意:元素雖然無放入順序,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實是固定的)
3、List介面有三個實現類:LinkedList,ArrayList,Vector ,Set介面有兩個實現類:HashSet(底層由HashMap實現),LinkedHashSet
F. 如何利用Java代碼實現List集合轉換成Set集合
Set和List都是介面,都實現了Collection介面和Iterable介面。
兩者的轉換不常進行,通過集合的 addAll() 方法可以實現
/**
*List和Set的轉化(Set轉化成List)
*/
publicstatic<T>List<T>SetToList(Set<T>set){
List<T>list=newArrayList<>();
list.addAll(set);//轉換核心
returnlist;
}
G. java中 List 與Set 的區別
其實就實際開發中List使用的次數更多一點,
假如從資料庫里讀了很多條記錄 經過處理封裝成對象 就可以裝在一個該對象類型的list裡面 就可以迭代訪問裡面每個對象,裡面的對象是有順序的,只有索引,你不能通過對他們取別的名字之類的得到她。
而set只能對應true or false,比方可以存放一個班上一門課作業是否提交,那bool assignment = set('小張'),就可以得到小張的作業是否已經提交list的話,就好比一個數組,存放一類對象的組合,一個容器,跟上面List性質不一樣的,可以想像成是一個可以動態變大變小的數組就可以了。
簡單來說就是
List : 存放有序可重復的元素
set : 存放無序不可重復的元素