java隨筆

static變量和static方法

static變量

1.static修飾的變量:靜態(tài)變量,靜態(tài)變量在內(nèi)存中只有一個拷貝,jvm只為靜態(tài)變量分配一次內(nèi)存久妆,在加載類的過程中完成靜態(tài)變量的內(nèi)存分配窒升。可以類名直接訪問赡矢。一般在對象之間共享值時和方便訪問變量時使用靜態(tài)變量杭朱。

2.實例變量,每創(chuàng)建一個實例就會為實例變量分配一次內(nèi)存吹散,實例變量可以有多個拷貝弧械,互不影響。

靜態(tài)方法

靜態(tài)方法可以直接通過類名調(diào)用空民,實例也可調(diào)用刃唐。靜態(tài)方法中不能使用this和super關鍵字,不能直接訪問所屬類的實例變量和實例方法袭景,只能訪問所屬類的靜態(tài)成員變量和成員方法唁桩。

static代碼塊

    public class Test5 {    
    private static int a;    
    private int b;    
     
    static{    
    Test5.a=3;    
    System.out.println(a);    
    Test5 t=new Test5();    
    t.f();    
    t.b=1000;    
    System.out.println(t.b);    
    }

在類中獨立于類成員的static語句塊,可以有多個耸棒,jvm加載類時會按順序執(zhí)行靜態(tài)代碼塊

static final

static final修飾的變量荒澡,表示一旦賦值就不可修改,并且可以通過類名訪問
static final修飾的方法与殃,不可覆蓋单山,可通過類名直接訪問

java支持的數(shù)據(jù)類型有碍现?何為自動拆裝箱?

1.byte

2.short

3.int

4.long

5.float

6.double

7.boolean

8.char
自動裝箱時java編譯器在基本數(shù)據(jù)類型和對應的對象包裝類型之間做的一個轉(zhuǎn)化米奸,比如int轉(zhuǎn)成Integer,double轉(zhuǎn)double等昼接,反之就是自動拆箱

java不支持多繼承。每個類只能繼承一個類悴晰,但可以實現(xiàn)多個接口

抽象類和抽象接口

java提供和創(chuàng)建抽象類和接口慢睡,不同點
1.接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法铡溪。

2.類可以實現(xiàn)很多個接口漂辐,但是只能繼承一個抽象類

3.類如果要實現(xiàn)一個接口,它必須要實現(xiàn)接口聲明的所有方法棕硫。但是髓涯,類可以不實現(xiàn)抽象類聲明的所有方法,當然哈扮,在這種情況下纬纪,類也必須得聲明成是抽象的。

4.抽象類可以在不提供接口方法實現(xiàn)的情況下實現(xiàn)接口滑肉。

5.Java接口中聲明的變量默認都是final的包各。抽象類可以包含非final的變量。

6.Java接口中的成員函數(shù)默認是public的赦邻。抽象類的成員函數(shù)可以是private髓棋,protected或者是public。

7惶洲。接口是絕對抽象的,不可以被實例化膳犹。抽象類也不可以被實例化恬吕,但是,如果它包含main方法的話是可以被調(diào)用的须床。

創(chuàng)建線程的幾種方式*

  1. 繼承thread類
  2. 實現(xiàn)Runnable接口
  3. 使用Executor框架來創(chuàng)建線程池
    java不支持多繼承铐料,實現(xiàn)接口的方式更受歡迎

synchronized獲取鎖,同步*

在監(jiān)視器內(nèi)部豺旬,如何做線程同步钠惩?程序應做何種級別的同步

監(jiān)視器和鎖在Java虛擬機中是一塊使用的。監(jiān)視器監(jiān)視一塊同步代碼塊族阅,確保一次只有一個線程執(zhí)行同步代碼塊篓跛。每一個監(jiān)視器

hashMap的原理

hashMap以key-value的形式進行數(shù)據(jù)存儲,本質(zhì)上是數(shù)組和鏈表的結(jié)合坦刀。

initialCapacity(初始容量)和loadFactor(加載因子)是影響hashMap性能的重要參數(shù)愧沟。默認初始容量16蔬咬,加載因子是0.75。為了保證HashMap的效率沐寺,系統(tǒng)必須要在某個臨界點進行擴容處理林艘,臨界點:當HashMap中元素的數(shù)量=數(shù)據(jù)長度length*加載因子(loadFactor).擴容是一個非常耗時的過程,需要重新計算數(shù)據(jù)在數(shù)組中的位置并進行復制混坞。

實驗表明length=2的n次方時狐援,數(shù)組中元素分布較均勻
過程:

  1. 利用key的hashCode重新hash計算出當前對象的元素在數(shù)組中的下標,然后找到在數(shù)組中的位置究孕。
  2. 如果hash值相同且key值也相同咕村,則覆蓋原始值;如果hash相同key不同(出現(xiàn)沖突)蚊俺,則將當前的key-value放入鏈表中

hashMap和hashTable懈涛、ConcurrentHashMap和synchronized Map的原理和區(qū)別(出處:http://www.importnew.com/21396.html

HashMap中key可以為null,HashTable中key不可以為null泳猬,ConcurrentHashMap中key和value都不能為null
HashMap是非線程安全的
如何線程安全的使用hashMap
Map<String,String> hashTable = new HashTable<String,String>()
Map<String,String> synchronizedMap = Collections.synchronizedMap(new HashMap<String,String>)
Map<String,String> concurrentHashMap = new ConcurrentHashMap<String,String>();
HashMap何時會產(chǎn)生死循環(huán)批钠?

HashTable

HashTable源碼中使用synchronized來保證線程安全,如get方法和put方法
public synchronized V get(Object key){
//省略
}
public synchronized V put(Object key){
//省略
}
當一個線程使用put方法時別的線程不但不可以使用put得封,連get方法都不可以使用埋心,效率低!現(xiàn)已基本不使用

ConcurrentHashMap

ConcurrentHashMap線程安全的忙上,適用于讀者數(shù)量大于寫者數(shù)量的場景

  1. 允許并發(fā)讀和線程安全的更新操作
  2. 在執(zhí)行寫操作時拷呆,只鎖住部分map
  3. 高的并發(fā)級別會造成時間和空間的浪費,低的并發(fā)級別在寫線程多時會引起線程間的競爭
  4. 返回的迭代器是弱一致性疫粥,fail-safe并且不會拋出ConcurrentModificationException異常
  5. 不允許null的鍵值
  6. 可代替HashTable,但CHM不會鎖住整個map
java7

采用鎖分離技術茬斧,使用多個鎖來控制hash表的不同部分,每一部分相當于一個hashTable梗逮,有自己的鎖项秉。只要多個修改操作發(fā)生在不同的segment上,就可以并發(fā)執(zhí)行慷彤。
有些方法需要跨段娄蔼,如size()和containsValue(),他們可能需要鎖定整個表而不僅僅是段,這需要按順序鎖定所有段底哗,操作完畢后岁诉,按順序釋放所有段的鎖

java8
synchronizedHashMap

源碼
//synchronizedMap方法
public static <K,V> Map<K,V>synchronizedMap(Map<K,V> m){
return new SynchronizedMap<>(m);
}
//SynchronizedMap類
private static class SynchronizedMap<K,V> implements Map<K,V> Serializable{
private static final long serialVersionUID = 1978198479659022715L;
private final Map<K,V> m; // Backing Map
final Object mutex; // Object on which to synchronize
SynchronizedMap(Map<K,V> m) {
this.m = Objects.requireNonNull(m);
mutex = this;
}
SynchronizedMap(Map<K,V> m, Object mutex) {
this.m = m;
this.mutex = mutex;
}
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
public boolean containsValue(Object value) {
synchronized (mutex) {return m.containsValue(value);}
}
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
synchronized (mutex) {return m.remove(key);}
}
// 省略其他方法
}
從源碼中可以看出,synchronizedMap()方法返回一個SynchronizedMap類的對象跋选,而在SynchronizedMap類中使用了synchronized同步關鍵字來保證對Map的操作是線程安全的

HashMap為什么是非線程安全涕癣?

void addEntry(int hash,K key,V value,int bucketIndex){
  Entry<K,V> e = table[bucketIndex];
  table[bucketIndex] = new Entry<K,V>(hash,key,value,e);
  if(size++ >= threshold){
    resize(2*table.length);
  }

}

原因一:hashMap做put操作的時候調(diào)用addEntry方法,現(xiàn)在假如A線程和B線程同時對同一個數(shù)據(jù)位置調(diào)用該方法野建,兩個線程會同時得到頭節(jié)點属划,A寫入頭節(jié)點以后B也寫入新的頭節(jié)點恬叹,那B的寫入操作造成A的寫入操作丟失。

addEntry中當加入新的鍵值對后鍵值對總數(shù)超過門限值的時候會調(diào)用一個resize操作同眯,代碼如下:
void resize(int newCapacity){
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if(oldCapacity == MAXIMUM_CAPACITY){
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
這個操作會生成一個新的容量的數(shù)組绽昼,會對原數(shù)組的所有鍵值對重新進行計算和寫入新的數(shù)組,之后指向新的數(shù)組须蜗。
原因二:當多個線程同時檢測需要進行resize()操作硅确,各自生成新的數(shù)組并rehash后賦給該map底層的數(shù)組table,結(jié)果最后只有一個線程生成的新數(shù)組被賦給table變量明肮,其他線程的均丟失菱农。
Map testmap = Collection.synchronizedMap(new HashMap())

equals()方法和hashCode()方法

java.lang.Object類中有兩個非常重要的方法
public boolean equals(Object obj)
public int hashCode()
Object是類繼承結(jié)構(gòu)的基礎,是所有類的父類

equals()

public boolean equals(Object obj){
    return (this == obj)
}

是對兩個對象的地址值進行比較柿估。但String循未、Math、Integer秫舌、Double等這些封裝類在使用equals()方法時的妖,已經(jīng)覆蓋了object類的equals()方法
如在String類中如下:
public boolean equals(Object anObject){
if(this == anObject){
return true;
}
if(anObject instanceof String){
String anotherString = (String)anObject;
int n = count;
if(n == anotherString.count){
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while(n-- != 0)//對每一位置逐一比較
{
if(v1[i++] != v2[j++]
return false;
}
}
return true;
}
}
return false;
}
類推Math、Integer足陨、Double等類都重寫了equals()方法嫂粟,還有基本類型也是進行內(nèi)容的比較

注意:當equals方法被override時,hashCode()也要被override墨缘。按照一般hashCode()方法的實現(xiàn)來說星虹,相等的對象镊讼,它們的hash code一定相等

hashCode

  1. 在一個java應用的執(zhí)行期間宽涌,如果一個對象提供給equals做比較的信息沒有被修改的話,該對象多次調(diào)用hashCode方法狠毯,始終返回同一個integer嚼松。
  2. 如果兩個對象根據(jù)equals(Object)方法是相等的,那調(diào)用二者各自的hashCode()方法必須產(chǎn)生同一個integer結(jié)果罕偎。
    在Object類中甩苛,hashCode定義如下:
    public native int hashCode();
    說明是本地方法讯蒲,實現(xiàn)跟本地機器有關墨林,如String犯祠、Integer搔耕、Double等這些類都覆蓋了hashCode方法,String中定義的hashCode()方法如下:
    public int hashCode(){
    int h = hash;
    if(h == 0){
    int off = offset;
    char val[] = value;
    int len = count;
    for(int i=0;i<len;i++){
    h = 31*h+val[off++];
    }
    hash = h;
    }
    return h;
    }

ArrayList 和 linkedList

  1. ArrayList實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)猜揪,LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)而姐。
  2. 對于隨機訪問,ArrayList優(yōu)于LinkedList
  3. 對于新增和刪除操作,LinkedList優(yōu)于ArrayList

ArrayList

ArrayList公般,在聲明對象時并不需要指定它的長度瞬雹,對象的大小是按照其中存儲的數(shù)據(jù)來動態(tài)擴充和收縮的胖缤。

數(shù)組擴容是對ArrayList效率影響較大的一個元素狗唉。
每當執(zhí)行Add、AddRange、insert、insertRange等添加元素的方法讥此,都會檢查內(nèi)部數(shù)組的容量是否夠用他巨。若不夠,以當前容量的兩倍來重新構(gòu)建數(shù)組染突,將舊元素COPY到數(shù)組中份企,然后丟棄舊數(shù)組

特定類型(Object除外)的數(shù)組的性能優(yōu)于ArrayList的性能棵介,因為ArrayList的元素屬于Object類型,所以在存儲或檢索值類型時通常發(fā)生裝箱和取消裝箱的操作冰啃。

map、list扇调、set

list 有序可重復
set 無序不可重復
map 按鍵值對存儲,無放入順序

List接口有三個實現(xiàn)類:LinkedList、ArrayList瑞侮、Vector
Set接口有兩個實現(xiàn)類:HashSet(底層由HashMap實現(xiàn)),LinkedHashSet
Map接口有三個實現(xiàn)類:HashMap种玛、HashTable、LinkedHashMap
HashMap allows one null key and any number of null values.稠歉,而Hashtable則不行
HashTable是synchronized的,是線程安全的,而HashMap不是

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猿诸,一起剝皮案震驚了整個濱河市北专,隨后出現(xiàn)的幾起案子禀挫,更是在濱河造成了極大的恐慌,老刑警劉巖拓颓,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件语婴,死亡現(xiàn)場離奇詭異,居然都是意外死亡驶睦,警方通過查閱死者的電腦和手機砰左,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來场航,“玉大人缠导,你說我怎么就攤上這事「攘。” “怎么了僻造?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵憋他,是天一觀的道長。 經(jīng)常有香客問我嫡意,道長举瑰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任蔬螟,我火速辦了婚禮,結(jié)果婚禮上汽畴,老公的妹妹穿的比我還像新娘旧巾。我一直安慰自己,他們只是感情好忍些,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布鲁猩。 她就那樣靜靜地躺著,像睡著了一般罢坝。 火紅的嫁衣襯著肌膚如雪廓握。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天嘁酿,我揣著相機與錄音隙券,去河邊找鬼。 笑死闹司,一個胖子當著我的面吹牛娱仔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播游桩,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼牲迫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了借卧?” 一聲冷哼從身側(cè)響起盹憎,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铐刘,沒想到半個月后陪每,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡滨达,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年奶稠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捡遍。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡锌订,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出画株,到底是詐尸還是另有隱情辆飘,我是刑警寧澤啦辐,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站蜈项,受9級特大地震影響芹关,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜紧卒,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一侥衬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跑芳,春花似錦轴总、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盆佣,卻和暖如春往堡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背共耍。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工虑灰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人征堪。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓瘩缆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親佃蚜。 傳聞我的和親對象是個殘疾皇子庸娱,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法谐算,內(nèi)部類的語法熟尉,繼承相關的語法,異常的語法洲脂,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • (一)Java部分 1斤儿、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,071評論 0 62
  • 一往果、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,254評論 0 16
  • 面向?qū)ο笾饕槍γ嫦蜻^程。 面向過程的基本單元是函數(shù)一铅。 什么是對象:EVERYTHING IS OBJECT(萬物...
    sinpi閱讀 1,045評論 0 4
  • 晚上接娃陕贮,通常是娃爹的活。我偶爾打個替班潘飘。 前幾天肮之,清明過后的那晚掉缺,雷電交加。我?guī)е鴥砂褌闳ソ铀昵堋砂褌愣夹U大的眶明,...
    息語閱讀 333評論 0 3