JDKフレームワークの概要--java.utilパッケージ内のツールクラスライブラリ
に記入
JDK,Java Development Kit.
まず、JDKはJavaベースクラスライブラリのセットにすぎず、Sun社が開発したベースクラスライブラリであることを認識しなければなりません.それだけです.JDK自体と私たちが自分でまとめたクラスライブラリは、技術的な含有量から言えば、やはり1つのレベルで、バイトコードにコンパイルされ、JREで実行される必要があります.JDKコンパイル後の結果はjre/libのrt.jarです.Javaに対する理解を深め、Java符号化のレベルを高めることを目的としています.
本シリーズのすべての文章に基づいたJDKバージョンは1.7である.16.
ソースのダウンロードアドレス:https://jdk7.java.net/source.html
本節の内容
このセクションではjavaを簡単に説明します.utilパッケージに含まれるツールクラスライブラリは,主に集合に関連するクラスライブラリであり,次いで正則,圧縮解凍,同時,日付時間などのツールクラスがある.
本編の内容はjavaについて大体、簡単です.utilパッケージは1つの説明を行って、後で次第に内容の補充を行って、本編の文章は1つのプレースホルダに相当して、いわゆる先に骨格があって、やっと次第に豊かになります
集合クラス
基本状況
プライマリ・インタフェースとその継承関係は次のとおりです.
SortedSet --> Set --> Collection --> Iterable
List --> Collection --> Iterable
SortedMap --> Map
共通クラスとその継承関係は次のとおりです.
HashSet/LinkedHashSet --> Set
TreeSet --> SortedSet --> Set
ArrayList/LinkedList --> List
HashMap --> Map
TreeMap --> SortedMap --> Map
統一呼称:Collection分岐のものを「集約」と呼ぶ.Mapブランチは、「マッピング」と呼ばれています.
CollectionはIterableから継承されるため、その下のクラスは反復器Iteratorでアクセスしたり、for(E e:es)でアクセスしたりすることができます.Mapは、その内部インタフェースEntryを実装したオブジェクトを要素として使用することができる.
HashtableとHashMapは、Mapインタフェースを実現しています.Hashtableは古い抽象クラスDictionaryから継承され、スレッドが安全です.HashMapは、スレッドが安全ではない新しい抽象クラスAbstractMapから継承されます.
HashMapはnullのキーと値を許可し、Hashtableはnullのキーと値を許可しない.
Hashtableにはメソッドcontainsメソッド(値が存在するか否かを判断する)があり、許可されるとkeyやvalueがnullであってもnullが返されるので誤解しやすいため、Hashtableは強制的に制限し、nullキーや値に対して直接Null PointerExceptionを投げ出す.
HashMapにはcontainsメソッドはなく,containsKey()とcontainsValues()である.
またJDK 5からは、スレッドセキュリティのMapに対してConcurrentHashMapがあり、効率的であり、スレッドセキュリティを実現する過程でsynchronizedを用いずにセグメント化された構造であり、CASというロックレスアルゴリズムでスレッドセキュリティを実現している.
Hash
Objectクラスには、オブジェクトの識別を推定する2つの方法があります.equals()とhashCode()です.
一般的に、どちらかを無視する場合は、両者の間に維持しなければならない重要な関係があるため、両方を同時に無視する必要があります.
特にequals()メソッドによれば、2つのオブジェクトが等しい場合、通常は本物ではないが、同じhashCode()値を持つ必要があります.
http://blog.sina.com.cn/s/blog_5dc351100101l57b.html
http://fhuan123.iteye.com/blog/1452275
HashMapのソースコード解析については、以下を参照してください.http://github.thinkingbar.com/hashmap-analysis/
LinkedHashMapは、HashMapの反復器、AddEntry、Entryなどのいくつかの方法とクラスを書き換え、要素が加わる順序を双方向チェーンテーブルで格納します.これはアクセス順に並べ替えることができ、最近アクセスした要素(get/put)はチェーンテーブルの末尾に置かれ、これはLRUアルゴリズム(Least Recenty Used)であり、最近最も少なくアルゴリズムを使用している.
ArrayListとLinkedList
ArrayListとLinkedListについては、ArrayListは配列に基づいており、このようにオブジェクトを連続した位置に置くことで読み取りが速くなるが、容量が不足した場合は配列拡張が必要となり、性能が低下し、挿入と削除も遅い.LinkedListはチェーンテーブルベースで、挿入も削除も速いが、検索が面倒でインデックス通りに検索できない.したがって、キューをArrayListまたはLinkedListとして構築するには、LinkedListにremoveLast()があり、ArrayListにはremove(index)しかありません.LinkedListでQueueを構築するコードは、以下のように説明されています.
ConcurrentModificationException
この場合javaを用いることができる.util.CopyOnWriteArrayListクラスのようなconcurrentパッケージの関連クラスでは、この異常は報告されません.CopyOnWriteArrayListクラスの最大の特徴は、インスタンスを変更(add/removeなど)すると、データが新規作成されて変更され、変更が完了した後、元の参照が新しい配列に指し示されます.これにより、変更プロセスで元の配列が変更されず、ConcurrentModificationExceptionエラーもなくなります.
CopyOnWriteArrayListのソースコードを参照してください.
ConcurrentModificationExceptionは、私が読んでいる内容が修正されたことを示していますが、もう一度遍歴する必要がありますか?それとも他の処理をしますか?これがfast-fail(高速失敗メカニズム)の意味です.
これは1つのスレッド内にあるだけで、マルチスレッドではありませんが、fast-failも同様に理解できます.
Fail-fastは、スレッドが自由に競争できるようにする同時楽観(optimistic)戦略の具体的な応用ですが、衝突が発生した場合、対応できると仮定します.つまり、問題が何なのかを判断し、解決策を与えることができます.
悲観(pessimistic)戦略は正反対で、それはいつも十分な制限を予め設定して、通常はロック(lock)を採用して、プログラムの進行中の間違いがないことを保証して、払う代価は他のスレッドの待機オーバーヘッドです.
高速失敗メカニズムの主な目的は、iteratorが配列を遍歴するスレッドが他のスレッドのMapに対する修正(put、remove、clearなど)をタイムリーに発見できるようにすることであるため、fast-failはすべての場合のマルチスレッドの同時エラーを保証することができず、iterator遍歴中のiterator.next()と書き込みの同時を保護するしかない.
TreeSetとCollections.sort
TreeSetはTreeMapに基づいて実現され、下位データ構造は「赤黒樹」であり、データの加入時に順序が整い、アクセスと検索性能はHashSetに及ばない.Collections.sortはリストを配列に変換してから「集計ソート」アルゴリズムを用いてソートし,集計ソートは安定したソートである.
TreeMapに関する記事:
http://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html
http://shmilyaw-hotmail-com.iteye.com/blog/1836431
http://www.ibm.com/developerworks/cn/java/j-lo-tree/index.html
http://blog.csdn.net/chenhuajie123/article/details/11951777
この2つのソートアルゴリズムの性能は、以下のように比較される(24コア、64 Gメモリ、RHEL 6.2).
データが基本的に順序付けされている場合、ソート要素の数は、あるセグメント(約2万-20万)でTreeSetがより効率的であり、他の数ではCollections.sortがより効率的である.
データのランダム性が強い場合、ソート要素の数は1万以内で、差は大きくありません.Collections.sort性能はやや高い.1万人を除いて80万人以内で、TreeSetの性能はCollectionsより明らかに高い.sort;80万ドルの外、Collection.sort性能がより高い.java.util.concurrent.ConcurrentSkipListSetという「ホップテーブル」に基づくスレッドの安全なソート可能クラスは、30万以内でCollectionより性能が高い.sort,30万以外はCollectionより性能が低い.sort,ConcurrentSkipListSetのソート性能は常にTreeSetより低い.
ConcurrentSkipListSetには、バランスのとれたツリーインデックス機構にはない利点があり、同時環境でよく機能することです.
ここで,SkipListのようなデータ構造を理解する前に,並べ替えベースのインデックス構造を同時環境で構築すると,赤黒ツリーが好ましいが,そのバランス操作にはツリー構造全体のロックが必要であり,同時環境では性能と伸縮性が悪いことが想像できる.
コードのデモは次のとおりです.
エラー検証:
増減のエラー検証を行ったところ、1つのオブジェクトに対してTreeSetを使用してソートし、同じデータEntryを使用してソートするのと比較して、パフォーマンスが悪いことがわかりました.最初はJDKがEntryを最適化したと思っていたが、static/finalなど、その後も対象をfinalに変更し、中の要素もfinalに変更したが、性能が依然として悪く、全く説明できず、理解できない感じがした.
その後、2つのセグメントのコードが一致していないことが判明し、Entryを使用してソートするコードにバグがあり、ソートするデータが少ないため、パフォーマンスが良いように見えます..
だから、無意味な憶測は不要で、JDKが深く理解した上で構築すればいいのです.
もう一つのソート構想
例えば、Top 20を取り出しても、必ずしもすべてソートする必要はありません.上位20個だけを取ることができます.経験証、小データ量の場合、性能も非常に高く、ビッグデータは検証されていません.コードは大体以下の通りです.
正規表現
一般的な開発言語では正規表現がサポートされていますが、正規表現に対するサポートの程度は異なります.
Js正則:http://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx
Python正則:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
Java正則:
http://www.blogjava.net/xzclog/archive/2006/09/19/70603.html
http://www.cnblogs.com/android-html5/archive/2012/06/02/2533924.html
同時関連クラス
次の章では、簡単な使用方法について説明します.http://blog.csdn.net/puma_dong/article/details/37597261#t5
圧縮解凍クラス
次の章では、簡単な使用方法について説明します.http://blog.csdn.net/puma_dong/article/details/23018555#t20
その他のツールクラス
タイマー、日付、時間、通貨など
JDK,Java Development Kit.
まず、JDKはJavaベースクラスライブラリのセットにすぎず、Sun社が開発したベースクラスライブラリであることを認識しなければなりません.それだけです.JDK自体と私たちが自分でまとめたクラスライブラリは、技術的な含有量から言えば、やはり1つのレベルで、バイトコードにコンパイルされ、JREで実行される必要があります.JDKコンパイル後の結果はjre/libのrt.jarです.Javaに対する理解を深め、Java符号化のレベルを高めることを目的としています.
本シリーズのすべての文章に基づいたJDKバージョンは1.7である.16.
ソースのダウンロードアドレス:https://jdk7.java.net/source.html
本節の内容
このセクションではjavaを簡単に説明します.utilパッケージに含まれるツールクラスライブラリは,主に集合に関連するクラスライブラリであり,次いで正則,圧縮解凍,同時,日付時間などのツールクラスがある.
本編の内容はjavaについて大体、簡単です.utilパッケージは1つの説明を行って、後で次第に内容の補充を行って、本編の文章は1つのプレースホルダに相当して、いわゆる先に骨格があって、やっと次第に豊かになります
集合クラス
基本状況
プライマリ・インタフェースとその継承関係は次のとおりです.
SortedSet --> Set --> Collection --> Iterable
List --> Collection --> Iterable
SortedMap --> Map
共通クラスとその継承関係は次のとおりです.
HashSet/LinkedHashSet --> Set
TreeSet --> SortedSet --> Set
ArrayList/LinkedList --> List
HashMap --> Map
TreeMap --> SortedMap --> Map
統一呼称:Collection分岐のものを「集約」と呼ぶ.Mapブランチは、「マッピング」と呼ばれています.
CollectionはIterableから継承されるため、その下のクラスは反復器Iteratorでアクセスしたり、for(E e:es)でアクセスしたりすることができます.Mapは、その内部インタフェースEntryを実装したオブジェクトを要素として使用することができる.
HashtableとHashMapは、Mapインタフェースを実現しています.Hashtableは古い抽象クラスDictionaryから継承され、スレッドが安全です.HashMapは、スレッドが安全ではない新しい抽象クラスAbstractMapから継承されます.
HashMapはnullのキーと値を許可し、Hashtableはnullのキーと値を許可しない.
Hashtableにはメソッドcontainsメソッド(値が存在するか否かを判断する)があり、許可されるとkeyやvalueがnullであってもnullが返されるので誤解しやすいため、Hashtableは強制的に制限し、nullキーや値に対して直接Null PointerExceptionを投げ出す.
HashMapにはcontainsメソッドはなく,containsKey()とcontainsValues()である.
またJDK 5からは、スレッドセキュリティのMapに対してConcurrentHashMapがあり、効率的であり、スレッドセキュリティを実現する過程でsynchronizedを用いずにセグメント化された構造であり、CASというロックレスアルゴリズムでスレッドセキュリティを実現している.
Hash
Objectクラスには、オブジェクトの識別を推定する2つの方法があります.equals()とhashCode()です.
一般的に、どちらかを無視する場合は、両者の間に維持しなければならない重要な関係があるため、両方を同時に無視する必要があります.
特にequals()メソッドによれば、2つのオブジェクトが等しい場合、通常は本物ではないが、同じhashCode()値を持つ必要があります.
http://blog.sina.com.cn/s/blog_5dc351100101l57b.html
http://fhuan123.iteye.com/blog/1452275
HashMapのソースコード解析については、以下を参照してください.http://github.thinkingbar.com/hashmap-analysis/
LinkedHashMapは、HashMapの反復器、AddEntry、Entryなどのいくつかの方法とクラスを書き換え、要素が加わる順序を双方向チェーンテーブルで格納します.これはアクセス順に並べ替えることができ、最近アクセスした要素(get/put)はチェーンテーブルの末尾に置かれ、これはLRUアルゴリズム(Least Recenty Used)であり、最近最も少なくアルゴリズムを使用している.
ArrayListとLinkedList
ArrayListとLinkedListについては、ArrayListは配列に基づいており、このようにオブジェクトを連続した位置に置くことで読み取りが速くなるが、容量が不足した場合は配列拡張が必要となり、性能が低下し、挿入と削除も遅い.LinkedListはチェーンテーブルベースで、挿入も削除も速いが、検索が面倒でインデックス通りに検索できない.したがって、キューをArrayListまたはLinkedListとして構築するには、LinkedListにremoveLast()があり、ArrayListにはremove(index)しかありません.LinkedListでQueueを構築するコードは、以下のように説明されています.
class Queue {
private LinkedList llt;
public Queue() {
llt = new LinkedList();
}
public void add(String s) {
llt.add(s);
}
public String get() {
return llt.removeLast(); //
//return llt.removeFirst(); //
}
public boolean isNull() {
return llt.isEmpty();
}
}
ConcurrentModificationException
import java.util.*;
import java.util.Map.Entry;
class Test
{
public static void main(String[] args) throws Exception {
HashMap mTemp = new HashMap();
mTemp.put("test1",1);
Iterator> iTemp = mTemp.entrySet().iterator();
// java.util.ConcurrentModificationException,
// , , (modCount != expectedModCount)
// Exception,
//mTemp.put("test2",2);
while(iTemp.hasNext()) {
System.out.println(iTemp.next().getKey());
}
//for , , ,
for(Entry e : mTemp.entrySet()) {
System.out.println(e.getKey());
}
ArrayList al = new ArrayList();
al.add("test");
for(String s : al) {
Integer i = Integer.reverse((new java.util.Random().nextInt(100)));
al.add(i.toString()); // ConcurrentModificationException
}
}
}
この場合javaを用いることができる.util.CopyOnWriteArrayListクラスのようなconcurrentパッケージの関連クラスでは、この異常は報告されません.CopyOnWriteArrayListクラスの最大の特徴は、インスタンスを変更(add/removeなど)すると、データが新規作成されて変更され、変更が完了した後、元の参照が新しい配列に指し示されます.これにより、変更プロセスで元の配列が変更されず、ConcurrentModificationExceptionエラーもなくなります.
CopyOnWriteArrayListのソースコードを参照してください.
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return true (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
ConcurrentModificationExceptionは、私が読んでいる内容が修正されたことを示していますが、もう一度遍歴する必要がありますか?それとも他の処理をしますか?これがfast-fail(高速失敗メカニズム)の意味です.
これは1つのスレッド内にあるだけで、マルチスレッドではありませんが、fast-failも同様に理解できます.
Fail-fastは、スレッドが自由に競争できるようにする同時楽観(optimistic)戦略の具体的な応用ですが、衝突が発生した場合、対応できると仮定します.つまり、問題が何なのかを判断し、解決策を与えることができます.
悲観(pessimistic)戦略は正反対で、それはいつも十分な制限を予め設定して、通常はロック(lock)を採用して、プログラムの進行中の間違いがないことを保証して、払う代価は他のスレッドの待機オーバーヘッドです.
高速失敗メカニズムの主な目的は、iteratorが配列を遍歴するスレッドが他のスレッドのMapに対する修正(put、remove、clearなど)をタイムリーに発見できるようにすることであるため、fast-failはすべての場合のマルチスレッドの同時エラーを保証することができず、iterator遍歴中のiterator.next()と書き込みの同時を保護するしかない.
TreeSetとCollections.sort
TreeSetはTreeMapに基づいて実現され、下位データ構造は「赤黒樹」であり、データの加入時に順序が整い、アクセスと検索性能はHashSetに及ばない.Collections.sortはリストを配列に変換してから「集計ソート」アルゴリズムを用いてソートし,集計ソートは安定したソートである.
TreeMapに関する記事:
http://zh.wikipedia.org/wiki/%E7%BA%A2%E9%BB%91%E6%A0%91
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html
http://shmilyaw-hotmail-com.iteye.com/blog/1836431
http://www.ibm.com/developerworks/cn/java/j-lo-tree/index.html
http://blog.csdn.net/chenhuajie123/article/details/11951777
この2つのソートアルゴリズムの性能は、以下のように比較される(24コア、64 Gメモリ、RHEL 6.2).
データが基本的に順序付けされている場合、ソート要素の数は、あるセグメント(約2万-20万)でTreeSetがより効率的であり、他の数ではCollections.sortがより効率的である.
データのランダム性が強い場合、ソート要素の数は1万以内で、差は大きくありません.Collections.sort性能はやや高い.1万人を除いて80万人以内で、TreeSetの性能はCollectionsより明らかに高い.sort;80万ドルの外、Collection.sort性能がより高い.java.util.concurrent.ConcurrentSkipListSetという「ホップテーブル」に基づくスレッドの安全なソート可能クラスは、30万以内でCollectionより性能が高い.sort,30万以外はCollectionより性能が低い.sort,ConcurrentSkipListSetのソート性能は常にTreeSetより低い.
ConcurrentSkipListSetには、バランスのとれたツリーインデックス機構にはない利点があり、同時環境でよく機能することです.
ここで,SkipListのようなデータ構造を理解する前に,並べ替えベースのインデックス構造を同時環境で構築すると,赤黒ツリーが好ましいが,そのバランス操作にはツリー構造全体のロックが必要であり,同時環境では性能と伸縮性が悪いことが想像できる.
コードのデモは次のとおりです.
import java.util.TreeSet;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Collections;
import java.util.Arrays;
import java.util.ListIterator;
import java.util.Random;
import java.util.Iterator;
class Test {
public static void main(String[] args) {
final int LEN = 300000;
final int SEED = 100000;
Random r = new Random();
System.out.println("---------------------------");
long b = System.currentTimeMillis();
TreeSet ts = new TreeSet(new Comparator(){
public int compare(Temp t1,Temp t2) {return t1.id-t2.id;}
});
for(int i=0;i aTemp = new ArrayList();
Iterator it = ts.iterator();
while(it.hasNext()) {
aTemp.add(it.next());
}
System.out.println(System.currentTimeMillis() - b);
System.out.println("---------------------------");
b = System.currentTimeMillis();
ArrayList al = new ArrayList();
for(int i=0;i() {
public int compare(Temp t1,Temp t2) {return t1.id-t2.id;}
});*/
Temp[] a = new Temp[al.size()];
al.toArray(a);
System.out.println(System.currentTimeMillis() - b);
Arrays.sort(a,new Comparator() {
public int compare(Temp t1,Temp t2) {return t1.id-t2.id;}
});
System.out.println(System.currentTimeMillis() - b);
ListIterator li = al.listIterator();
for(int i=0;i
エラー検証:
増減のエラー検証を行ったところ、1つのオブジェクトに対してTreeSetを使用してソートし、同じデータEntryを使用してソートするのと比較して、パフォーマンスが悪いことがわかりました.最初はJDKがEntryを最適化したと思っていたが、static/finalなど、その後も対象をfinalに変更し、中の要素もfinalに変更したが、性能が依然として悪く、全く説明できず、理解できない感じがした.
その後、2つのセグメントのコードが一致していないことが判明し、Entryを使用してソートするコードにバグがあり、ソートするデータが少ないため、パフォーマンスが良いように見えます..
だから、無意味な憶測は不要で、JDKが深く理解した上で構築すればいいのです.
もう一つのソート構想
例えば、Top 20を取り出しても、必ずしもすべてソートする必要はありません.上位20個だけを取ることができます.経験証、小データ量の場合、性能も非常に高く、ビッグデータは検証されていません.コードは大体以下の通りです.
int n = 0;
double minScore = 100; //Top20
String minKey = ""; // Key
Map skuTop = new HashMap();
Set styles = new HashSet(); //
for(String sku :tempSkuViewSkus.get(goodsUser.getKey())) {
boolean filter = false;
filter = filterSameStyle(sku,styles);
if(filter) continue;
// , continue
Set userSet = goodsUserView.get(sku);
if(userSet == null || userSet.size() == 0) continue;
// , , ( )
double score = mathTools.getJaccardSimilar(goodsUser.getValue(), userSet);
// 20 Map
if(n++ < ConstMongo.maxRecomNum) {
skuTop.put(sku, score);
if(score < minScore) {
minScore = score;
minKey = sku;
}
continue;
}
if(score <= minScore) continue;
//
skuTop.remove(minKey);
skuTop.put(sku, score);
minScore = score;
minKey = sku;
for(Entry e : skuTop.entrySet()) {
if(e.getValue() < minScore) {
minScore = e.getValue();
minKey = e.getKey();
}
}
}
正規表現
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Hello {
public static void main(String[] args)
{
Pattern pattern = Pattern.compile(" ");
//Pattern pattern = Pattern.compile("Hello, \\s[\\S]+");
Matcher matcher = pattern.matcher(" Hello, World");
//
System.out.println(matcher.replaceFirst("Java"));
}
}
一般的な開発言語では正規表現がサポートされていますが、正規表現に対するサポートの程度は異なります.
Js正則:http://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx
Python正則:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
Java正則:
http://www.blogjava.net/xzclog/archive/2006/09/19/70603.html
http://www.cnblogs.com/android-html5/archive/2012/06/02/2533924.html
同時関連クラス
次の章では、簡単な使用方法について説明します.http://blog.csdn.net/puma_dong/article/details/37597261#t5
圧縮解凍クラス
次の章では、簡単な使用方法について説明します.http://blog.csdn.net/puma_dong/article/details/23018555#t20
その他のツールクラス
タイマー、日付、時間、通貨など