日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

hashmap应用场景_工作中常用到的Java集合有哪些?应用场景是什么?

發布時間:2023/12/3 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashmap应用场景_工作中常用到的Java集合有哪些?应用场景是什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 秋招Java面試大綱:Java+并發+spring+數據庫+Redis+JVM+Netty等
  • 疫情期間“閉關修煉”,吃透這本Java核心知識,跳槽面試不心慌
  • Spring全家桶筆記:Spring+Spring Boot+Spring Cloud+Spring MVC

前言

Java集合是我認為在Java基礎中最最重要的知識點了,Java集合是必須掌握的。我在實習/秋招面試的時候,只要是面到Java,那一定是少不了Java集合

作為一個新人,最關心的其實有一點:這個技術在工作中是怎么用的。換個說法:“工作中常用到的Java集合有哪些,應用場景是什么”

List集合

List集合下最常見的集合類有兩個:ArrayList和LinkedList

在工作中,我都是無腦用ArrayList。我問了兩個同事:“你們在項目中用過LinkedList嗎?”他們都表示沒有。

眾所周知,ArrayList底層是數組,LinkedList底層是鏈表。數組遍歷速度快,LinkedList增刪元素快。

為什么在工作中一般就用ArrayList,而不用LinkedList呢?原因也很簡單:

  • 在工作中,遍歷的需求比增刪多,即便是增加元素往往也只是從尾部插入元素,而ArrayList在尾部插入元素也是O(1)
  • ArrayList增刪沒有想象中慢,ArrayList的增刪底層調用的copyOf()被優化過,加上現代CPU對內存可以塊操作,普通大小的ArrayList增刪比LinkedList更快。

所以,在開發中,想到要用集合來裝載元素,第一個想到的就是ArrayList。

那么來了,LinkedList用在什么地方呢?我們一般用在刷算法題上。把LinkedList當做一個先進先出的隊列,LinkedList本身就實現了Queue接口

如果考慮線程安全的問題,可以看看CopyWriteOnArrayList,實際開發用得不多,但我覺得可以了解一下它的思想(CopyWriteOn),這個思想在Linux/文件系統都有用到。

Set集合

Set集合下最常見的集合類有三個:HashSet、TreeSet、LinkedHashSet

List和Set都是集合,一般來說:如果我們需要保證集合的元素是唯一的,就應該想到用Set集合

比如說:現在要發送一批消息給用戶,我們為了減少「一次發送重復的內容給用戶」這樣的錯誤,我們就用Set集合來保存用戶的userId/phone

自然地,首先要保證最上游的那批用戶的userId/phone是沒有重復的,而我們用Set集合只是為了做一個兜底來盡可能避免重復發送的問題。

一般我們在開發中最多用到的也就是HashSet。TreeSet是可以排序的Set,一般我們需要有序,從數據庫拉出來的數據就是有序的,可能往往寫order by id desc比較多。而在開發中也很少管元素插入有序的問題,所以LinkedHashSet一般也用不上。

如果考慮線程安全的問題,可以考慮CopyOnWriteArraySet,用得就更少了(這是一個線程安全的Set,底層實際上就是CopyWriteOnArrayList)

TreeSet和LinkedHashSet更多的可能用在刷算法的時候。

Map集合

Map集合最常見的子類也有三個:HashMap、LinkedHashMap、TreeMap

如果考慮線程安全問題,應該想到的是ConcurrentHashMap,當然了Hashtable也要有一定的了解,因為面試實在是問得太多太多了。

HashMap在實際開發中用得也非常多,只要是key-value結構的,一般我們就用HashMap。LinkedHashMap和TreeMap用的不多,原因跟HashSet和TreeSet一樣。

ConcurrentHashMap在實際開發中也用得挺多,我們很多時候把ConcurrentHashMap用于本地緩存,不想每次都網絡請求數據,在本地做本地緩存。監聽數據的變化,如果數據有變動了,就把ConcurrentHashMap對應的值給更新了。

Queue隊列

不知道大家有沒有學過生產者和消費者模式,秋招面試的時候可能會讓你手寫一段這樣的代碼。最簡單的方式就是用阻塞隊列去寫。類似下面:

生產者:

import java.util.Random;import java.util.Vector;import java.util.concurrent.atomic.AtomicInteger;public class Producer implements Runnable { // true--->生產者一直執行,false--->停掉生產者 private volatile boolean isRunning = true; // 公共資源 private final Vector sharedQueue; // 公共資源的最大數量 private final int SIZE; // 生產數據 private static AtomicInteger count = new AtomicInteger(); public Producer(Vector sharedQueue, int SIZE) { this.sharedQueue = sharedQueue; this.SIZE = SIZE; } @Override public void run() { int data; Random r = new Random(); System.out.println("start producer id = " + Thread.currentThread().getId()); try { while (isRunning) { // 模擬延遲 Thread.sleep(r.nextInt(1000)); // 當隊列滿時阻塞等待 while (sharedQueue.size() == SIZE) { synchronized (sharedQueue) { System.out.println("Queue is full, producer " + Thread.currentThread().getId() + " is waiting, size:" + sharedQueue.size()); sharedQueue.wait(); } } // 隊列不滿時持續創造新元素 synchronized (sharedQueue) { // 生產數據 data = count.incrementAndGet(); sharedQueue.add(data); System.out.println("producer create data:" + data + ", size:" + sharedQueue.size()); sharedQueue.notifyAll(); } } } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupted(); } } public void stop() { isRunning = false; }}

消費者:

import java.util.Random;import java.util.Vector;public class Consumer implements Runnable { // 公共資源 private final Vector sharedQueue; public Consumer(Vector sharedQueue) { this.sharedQueue = sharedQueue; } @Override public void run() { Random r = new Random(); System.out.println("start consumer id = " + Thread.currentThread().getId()); try { while (true) { // 模擬延遲 Thread.sleep(r.nextInt(1000)); // 當隊列空時阻塞等待 while (sharedQueue.isEmpty()) { synchronized (sharedQueue) { System.out.println("Queue is empty, consumer " + Thread.currentThread().getId() + " is waiting, size:" + sharedQueue.size()); sharedQueue.wait(); } } // 隊列不空時持續消費元素 synchronized (sharedQueue) { System.out.println("consumer consume data:" + sharedQueue.remove(0) + ", size:" + sharedQueue.size()); sharedQueue.notifyAll(); } } } catch (InterruptedException e) { e.printStackTrace(); Thread.currentThread().interrupt(); } }}

Main方法測試:

import java.util.Vector;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test2 { public static void main(String[] args) throws InterruptedException { // 1.構建內存緩沖區 Vector sharedQueue = new Vector(); int size = 4; // 2.建立線程池和線程 ExecutorService service = Executors.newCachedThreadPool(); Producer prodThread1 = new Producer(sharedQueue, size); Producer prodThread2 = new Producer(sharedQueue, size); Producer prodThread3 = new Producer(sharedQueue, size); Consumer consThread1 = new Consumer(sharedQueue); Consumer consThread2 = new Consumer(sharedQueue); Consumer consThread3 = new Consumer(sharedQueue); service.execute(prodThread1); service.execute(prodThread2); service.execute(prodThread3); service.execute(consThread1); service.execute(consThread2); service.execute(consThread3); // 3.睡一會兒然后嘗試停止生產者(結束循環) Thread.sleep(10 * 1000); prodThread1.stop(); prodThread2.stop(); prodThread3.stop(); // 4.再睡一會兒關閉線程池 Thread.sleep(3000); // 5.shutdown()等待任務執行完才中斷線程(因為消費者一直在運行的,所以會發現程序無法結束) service.shutdown(); }}

我的項目用阻塞隊列也挺多的(我覺得跟個人編寫的代碼風格習慣有關),類似實現了上面的生產者和消費者模式。

真實場景例子:

  • 運營要發一條推送消息,首先需要去用戶畫像系統圈選一個人群,填寫對應的人群ID和發送時間。
  • 我通過時間調度,通過RPC拿到人群的信息。遍歷HDFS得到這個人群的每個userId
  • 將遍歷的userId放到一個阻塞隊列里邊去,用多個線程while(true)取阻塞隊列的數據

好處是什么?我在取userId的時候,會有個限制:要么超出了指定的時間,要么達到BatchSize的值。這樣我就可以將相同內容的不同userId組成一個Task

本來100個userId是100個Task,現在我將100個userId放在一個Task里邊(因為發送的內容是相同的,所以我可以這么干)。這樣再往下游傳的時候,并發量就降低了很多。

什么時候考慮線程安全

什么時候考慮線程安全的集合類,那當然是線程不安全的時候咯。那什么時候線程不安全?最常見的是:操作的對象是有狀態的

雖然說,我們經常會聽到線程不安全,但在業務開發中要我們程序員處理線程不安全的地方少之又少。比如說:你在寫Servlet的時候,加過syn/lock鎖嗎?應該沒有吧?

因為我們的操作的對象往往是無狀態的。沒有共享變量被多個線程訪問,自然就沒有線程安全問題了

SpringMVC是單例的,但SpringMVC都是在方法內操作數據的,每個線程進入方法都會生成棧幀,每個棧幀的數據都是線程獨有的,如果不設定共享變量,不會有線程安全問題。

上面只是簡單舉了SpringMVC的例子(只是為了更好的理解);

一句話總結:只要涉及到多個線程操作一個共享變量的時候,就要考慮是不是要用線程安全的集合類

最后

還是想強調一下,Java集合雖然在工作中不是每個都經常用得到,但是還是得重點學習學習。

如果你學習到了源碼,可能你在創建集合的時候就會指定了集合的大小(即便我們知道它能動態擴容)

如果你想要去面試,Java集合是肯定少不了的,必問的一個知識點,你學會了就是送分題

現在已經工作有一段時間了,為什么還來寫Java集合呢,原因有以下幾個:

  • 我是一個對排版有追求的人,如果早期關注我的同學可能會發現,我的GitHub、文章導航的read.me會經常更換。現在的GitHub導航也不合我心意了(太長了),并且早期的文章,說實話排版也不太行,我決定重新搞一波。
  • 我的文章會分發好幾個平臺,但文章發完了可能就沒人看了,并且圖床很可能因為平臺的防盜鏈就掛掉了。又因為有很多的讀者問我:”你能不能把你的文章轉成PDF啊?“
  • 我寫過很多系列級的文章,這些文章就幾乎不會有太大的改動了,就非常適合把它們給”持久化“。


作者:Java3y
原文鏈接:https://juejin.im/post/5e7c05236fb9a009a6764ef9

總結

以上是生活随笔為你收集整理的hashmap应用场景_工作中常用到的Java集合有哪些?应用场景是什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品人妻少妇嫩草av无码 | 亚洲精品www久久久久久 | 成人福利在线视频 | 91情侣视频 | 日本高清黄色电影 | 国产91传媒| 午夜免费成人 | 在线观看视频www | 日韩porn| 色香欲综合网 | 国产chinese男男网站大全 | 超碰99在线 | 91国产中文字幕 | 国产美女无遮挡永久免费 | 伊人91视频 | 久久精品区 | 中文字幕在线播放不卡 | 成人28深夜影院 | 我和我的太阳泰剧在线观看泰剧 | 播放黄色一级片 | 欧美成人精品在线视频 | 日韩精品三区 | 国产91色 | 婷婷狠狠干| 欧美交 | aaaaaabbbbbb毛片 | 亚洲精品免费在线观看 | 亲子乱对白乱都乱了 | 日韩高清在线 | 成人国产精品蜜柚视频 | 色偷偷av一区二区三区 | 国产精品视频你懂的 | 久久精品视屏 | 国产色无码精品视频国产 | 五月婷婷视频在线观看 | 五月天激情四射 | 久久亚洲电影 | 久久黄色录像 | 另类小说五月天 | 少妇不卡视频 | 欧美日韩伊人 | 人妻夜夜爽天天爽三区麻豆av网站 | 日本高清二区 | 古代黄色片| 婷婷久久网 | 国产精品成人国产乱一区 | n0659极腔濑亚美莉在线播放播放 | 日本成人免费在线视频 | 久久久久久色 | 黄色一级视频 | youjizz.com中国 | 日本大胆欧美人术艺术 | 99精品区 | 欧美成人黄色小说 | 中文字幕一区二区三区不卡 | 中国大陆毛片 | 久久99国产精品 | 午夜亚洲aⅴ无码高潮片苍井空 | 蜜臀一区二区三区精品免费视频 | 福利视频亚洲 | 男生女生插插插 | 老外黄色一级片 | 别揉我奶头一区二区三区 | 天使色吧 | 在线观看亚洲国产 | 午夜影院操 | 久久亚洲综合网 | 美女网站免费观看视频 | 久久久久国产 | 香港一级淫片免费放 | 亚洲九九 | av操操 | 亚洲一区二区精品 | av网站免费观看 | 日韩欧美黄色网址 | 97se在线 | 美女的诞生免费观看在线高清 | 天天干天天搞天天射 | 亚洲一二三四区 | 少妇裸体性生交 | 成人日韩欧美 | 国产做受高潮漫动 | 小色哥网站 | 欧美在线视频免费播放 | 欧美高清视频在线观看 | 色姑娘天天操 | 亚洲欧美日韩一区二区三区在线观看 | 亚洲a网站 | 久久不卡 | 亚洲欧美另类一区 | 国产欧美精品久久 | 欧美一区二区性久久久 | 精品久久久久一区二区国产 | 日本在线高清 | 夜夜爱爱 | 香蕉网久久 | 熟妇人妻中文字幕 | 国产日韩在线一区 | 中文字幕在线看高清电影 |