最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java集合類源碼分析之Set詳解

 更新時間:2017年10月10日 09:30:55   作者:Wilange  
下面小編就為大家?guī)硪黄猨ava集合類源碼分析之Set詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Set集合與List一樣,都是繼承自Collection接口,常用的實現(xiàn)類有HashSet和TreeSet。值得注意的是,HashSet是通過HashMap來實現(xiàn)的而TreeSet是通過TreeMap來實現(xiàn)的,所以HashSet和TreeSet都沒有自己的數(shù)據(jù)結(jié)構(gòu),具體可以歸納如下:

•Set集合中的元素不能重復(fù),即元素唯一

•HashSet按元素的哈希值存儲,所以是無序的,并且最多允許一個null對象

•TreeSet按元素的大小存儲,所以是有序的,并且不允許null對象

•Set集合沒有g(shù)et方法,所以只能通過迭代器(Iterator)來遍歷元素,不能隨機訪問

1.HashSet

下面給出HashSet的部分源碼,以理解它的實現(xiàn)方式。

static final long serialVersionUID = -5024744406713321676L;

 private transient HashMap<E,Object> map;

 // Dummy value to associate with an Object in the backing Map
 private static final Object PRESENT = new Object();

觀察源碼,我們知道HashSet的數(shù)據(jù)是存儲在HashMap的實例對象map中的,并且對應(yīng)于map中的key,而Object類型的引用PRESENT則是對應(yīng)于map中的value的一個虛擬值,沒有實際意義。聯(lián)想到HashMap的一些特性:無序存儲、key值唯一等等,我們就可以很自然地理解Set集合元素不能重復(fù)以及HashSet無序存儲的特性了。

下面從源代碼的角度來理解HashSet的基本用法:

•構(gòu)造器(四種)

1.HashSet() 空的構(gòu)造器,初始化一個空的HashMap

2.HashSet(Collection<? extends E> c) 傳入一個子集c,用于初始化HashMap

3.HashSet(int initialCapacity, float loadFactor) 初始化一個空的HashMap,并指定初始容量和加載因子

4.HashSet(int initialCapacity) 初始化一個空的HashMap,并指定初始容量

public HashSet() {
  map = new HashMap<>();
 }

 public HashSet(Collection<? extends E> c) {
  map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
  addAll(c);
 }

 public HashSet(int initialCapacity, float loadFactor) {
  map = new HashMap<>(initialCapacity, loadFactor);
 }

 public HashSet(int initialCapacity) {
  map = new HashMap<>(initialCapacity);
 }

•插入元素

1.add(E e) 插入指定元素(調(diào)用HashMap的put方法實現(xiàn))

   Set<String> hashSet = new HashSet<String>();
   hashSet.add("D");
   hashSet.add("B");
   hashSet.add("C");
   hashSet.add("A");

•查找元素

1.contains(Object o) 判斷集合中是否包含指定的元素(調(diào)用HashMap的containsKey方法實現(xiàn))

  public boolean contains(Object o) {
   return map.containsKey(o);
  }

2.由于HashSet的實現(xiàn)類中沒有g(shù)et方法,所以只能通過迭代器依次遍歷,而不能隨機訪問(調(diào)用HashMap中keySet的迭代器實現(xiàn))

  public Iterator<E> iterator() {
   return map.keySet().iterator();
  }

應(yīng)用示例:

Set<String> hashSet = new HashSet<String>();
  hashSet.add("D");
  hashSet.add("B");
  hashSet.add("C");
  hashSet.add("A");
  for (Iterator iterator = hashSet.iterator(); iterator.hasNext();) {
   String string = (String) iterator.next();
   System.out.print(string+" ");
  }//D A B C

•修改元素

由于HashMap中的key值不能修改,所以HashSet不能進行修改元素的操作

•刪除元素

1.remove(Object o) 刪除指定元素(調(diào)用HashMap中的remove方法實現(xiàn),返回值為true或者false)

  public boolean remove(Object o) {
   return map.remove(o)==PRESENT;
  }

2.clear() 清空元素(調(diào)用HashMap中的clear方法實現(xiàn),沒有返回值)

public void clear() {
   map.clear();
  }

2.TreeSet

TreeSet是SortedSet接口的唯一實現(xiàn)類。前面說過,TreeSet沒有自己的數(shù)據(jù)結(jié)構(gòu)而是通過TreeMap實現(xiàn)的,所以TreeSet也是基于紅黑二叉樹的一種存儲結(jié)構(gòu),所以TreeSet不允許null對象,并且是有序存儲的(默認升序)。

private transient NavigableMap<E,Object> m;
 
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

上述源代碼中的NavigableMap是繼承自SrotedMap的一個接口,其實現(xiàn)類為TreeMap,因此TreeSet中的數(shù)據(jù)是通過TreeMap來存儲的,此處的PRESENT也是沒有實際意義的虛擬值。

下面從源代碼的角度來理解HashSet的基本用法:

•構(gòu)造器(四種)

1.TreeSet() 空的構(gòu)造器,初始化一個空的TreeMap,默認升序排列

2.TreeSet(Comparator<? super E> comparator) 傳入一個自定義的比較器,常常用于實現(xiàn)降序排列

3.TreeSet(Collection<? extends E> c) 傳入一個子集c,用于初始化TreeMap對象,默認升序

4.TreeSet(SortedSet<E> s) 傳入一個有序的子集s,用于初始化TreeMap對象,采用子集的比較器

public TreeSet() {
  this(new TreeMap<E,Object>());
 }

 public TreeSet(Comparator<? super E> comparator) {
  this(new TreeMap<>(comparator));
 }

 public TreeSet(Collection<? extends E> c) {
  this();
  addAll(c);
 }

 public TreeSet(SortedSet<E> s) {
  this(s.comparator());
  addAll(s);
 }

應(yīng)用示例

//自定義一個比較器,實現(xiàn)降序排列
  Set<Integer> treeSet = new TreeSet<Integer>(new Comparator<Integer>() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默認升序
    return o2.compareTo(o1);//降序
   }
  });
  treeSet.add(200);
  treeSet.add(120);
  treeSet.add(150);
  treeSet.add(110);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110
ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  //傳入一個子集,默認升序排列
  TreeSet<Integer> treeSet = new TreeSet<Integer>(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300
/*
   * 傳入一個有序的子集,采用子集的比較器
   *  注意子集的類型必須是SortedSet及其子類或者實現(xiàn)類,否則將采用默認的比較器
   *  所以此處subSet的類型也可以是TreeSet。
   */
  
  SortedSet<Integer> subSet = new TreeSet<Integer>(new Comparator<Integer>() {

   @Override
   public int compare(Integer o1, Integer o2) {
//    return 0;  //默認升序
    return o2.compareTo(o1);//降序
   }
  });
  subSet.add(200);
  subSet.add(120);
  subSet.add(150);
  subSet.add(110);
  for (Iterator iterator = subSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  } //200 150 120 110 
  
  System.out.println();
  Set<Integer> treeSet = new TreeSet<Integer>(subSet);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//200 150 120 110 
  
  System.out.println();
  treeSet.add(500);
  treeSet.add(100);
  treeSet.add(105);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//500 200 150 120 110 105 100

• 插入元素

1.add(E e) 插入指定的元素(調(diào)用TreeMap的put方法實現(xiàn))

2.addAll(Collection<? extends E> c) 插入一個子集c

ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set<Integer> treeSet = new TreeSet<Integer>();
  
  //插入一個子集,默認升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300

•查找元素

1.contains(Object o) 判斷集合中是否包含指定對象(調(diào)用TreeMap的containsKey方法實現(xiàn))

2.與HashSet一樣,TreeSet的實現(xiàn)類中沒有g(shù)et方法,所以只能通過迭代器依次遍歷,而不能隨機訪問(調(diào)用TreeMap中keySet的迭代器實現(xiàn))。

•修改元素

TreeSet不能進行修改元素的操作,原因與HashSet一樣。

•刪除元素

1.remove(Object o) 刪除指定元素(調(diào)用TreeMap中的remove方法實現(xiàn),返回true或者false)

  public boolean remove(Object o) {
   return m.remove(o)==PRESENT;
  }

2.clear() 清空元素(調(diào)用TreeMap中的clear方法實現(xiàn),無返回值)

  public void clear() {
   m.clear();
  } 

應(yīng)用示例:

ArrayList<Integer> list = new ArrayList<Integer>();
  list.add(300);
  list.add(120);
  list.add(100);
  list.add(150);
  System.out.println(list); //[300, 120, 100, 150]
  
  Set<Integer> treeSet = new TreeSet<Integer>();
  
  //插入一個子集,默認升序
  treeSet.addAll(list);
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//100 120 150 300 
  
  System.out.println(treeSet.remove(100));//true
  for (Iterator iterator = treeSet.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   System.out.print(integer+" ");
  }//120 150 300 
  
  treeSet.clear();
  System.out.println(treeSet.size());//0

至此,HashSet和TreeSet的存儲結(jié)構(gòu)及基本用法介紹完畢。

以上這篇java集合類源碼分析之Set詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • list的4種遍歷方式(實例講解)

    list的4種遍歷方式(實例講解)

    下面小編就為大家?guī)硪黄猯ist的4種遍歷方式(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java Validation Api使用方法實例解析

    Java Validation Api使用方法實例解析

    這篇文章主要介紹了Java Validation Api使用方法實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    SpringBoot中l(wèi)ogback日志保存到mongoDB的方法

    這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,
    2017-11-11
  • 關(guān)于intellij idea打開就閃退或關(guān)閉詳細解決辦法

    關(guān)于intellij idea打開就閃退或關(guān)閉詳細解決辦法

    這篇文章主要介紹了關(guān)于intellij idea打開就閃退或關(guān)閉詳細解決辦法,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • java版實現(xiàn)2048游戲功能

    java版實現(xiàn)2048游戲功能

    這篇文章主要為大家詳細介紹了java版實現(xiàn)2048游戲功能,相加數(shù)字出現(xiàn)2048即可,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 詳解Jmeter中的BeanShell腳本

    詳解Jmeter中的BeanShell腳本

    BeanShell是一種完全符合Java語法規(guī)范的腳本語言,并且又擁有自己的一些語法和方法,所以它和java是可以無縫銜接的,學(xué)了Java的一些基本語法后,就可以來在Jmeter中寫寫B(tài)eanShell腳本了
    2021-12-12
  • Springboot中項目的屬性配置的詳細介紹

    Springboot中項目的屬性配置的詳細介紹

    很多時候需要用到一些配置的信息,這些信息可能在測試環(huán)境和生產(chǎn)環(huán)境下會有不同的配置,本文主要介紹了Springboot中項目的屬性配置的詳細介紹,感興趣的可以了解一下
    2022-01-01
  • 淺談幾種Java自定義異常處理方式

    淺談幾種Java自定義異常處理方式

    在Java中,異常是一種常見的處理機制,本文主要介紹了淺談幾種Java自定義異常處理方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2023-05-05
  • Spring中自動裝配的4種方式

    Spring中自動裝配的4種方式

    今天小編就為大家分享一篇關(guān)于Spring中自動裝配的4種方式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • idea中如何使用(Undo Commit...)

    idea中如何使用(Undo Commit...)

    這篇文章主要介紹了idea中如何使用(Undo Commit...)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論

贺兰县| 陆丰市| 呼图壁县| 理塘县| 井冈山市| 兴和县| 青神县| 阿巴嘎旗| 北碚区| 兴化市| 团风县| 黑山县| 枝江市| 中阳县| 克什克腾旗| 枝江市| 澄迈县| 龙州县| 赤水市| 贵定县| 麻城市| 金塔县| 林西县| 裕民县| 泽普县| 灵寿县| 惠东县| 抚松县| 类乌齐县| 积石山| 固安县| 申扎县| 金门县| 黑龙江省| 和顺县| 红安县| 开鲁县| 杭州市| 邹城市| 滁州市| 日照市|