質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

4116閲覧

ThreadLocalに値が入る仕組みが分からない

y_matsumoto

総合スコア13

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/07/07 02:48

** 前提・実現したいこと**
ThreadLocalを使用しているresultPoolは、codes.forEachの
resultCodes.add(code);を行うことでcodeの値を取得することができますが、何故このタイミングでresultPoolに値が入るのかが私には分からず、困っております。
申し訳ありませんが、分かる方教えていただきたく思います。

該当のソースコード

java

1protected ThreadLocal<TreeSet<String>> resultPool = 2new ThreadLocal<TreeSet<String>>(); 3 4 5 protected void addResults(List<String> codes) { 6 TreeSet<String> resultCodes = resultPool.get(); 7 8 codes.forEach(code -> { 9 if (!resultCodes.contains(code)) { 10 resultCodes.add(code); 11 } 12 }); 13}

補足情報(言語/FW/ツール等のバージョンなど)
addResults(List<String> codes)のcodesには
0000,0001,0002,0003,0004,0005
が格納されています。

Java8 eclipse4.5で開発しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

すみません。どこを不可思議に思っているかどうかが把握できてないので教えてください。
addResultsをやるとどこでresultPoolの中身をとりだしても値が入っているのが不思議ということでしょうか?

Java

1//どこかでこれを先にやる 2List<String> codes = new ArrayList<>(); 3codes.add("0000"); 4codes.add("0001"); 5codes.add("0002"); 6addResults(codes); 7 8//別のメソッドで 9TreeSet<String> hoge = resultPool.get(); 10hoge.forEach(val->{ 11 System.out.println(val);//0000,0001,0002が出力されるのが謎? 12});

※ちなみに下記コードの(1)(2)は問題なく理解できますか?

Java

1private static TreeSet<String> set = new TreeSet<>(); 2 3private static Map<Integer,TreeSet<String>> setMap = new HashMap<>(); 4static { 5 setMap.put(1, new TreeSet<>()); 6} 7 8public static void main(String[] args) { 9 //(1) 10 set.add("A"); 11 set.add("B"); 12 TypeA a= new TypeA(); 13 a.print();//A,Bが出力 14 //(2) 15 TreeSet<String> hs = setMap.get(1); 16 hs.add("C"); 17 hs.add("D"); 18 TypeB b= new TypeB(); 19 b.print();//C,Dが出力 20 21} 22 23static class TypeA { 24 void print(){ 25 set.forEach(val->{ 26 System.out.println(val); 27 }); 28 } 29} 30 31static class TypeB { 32 void print(){ 33 TreeSet<String> set2 = setMap.get(1); 34 set2.forEach(val->{ 35 System.out.println(val); 36 }); 37 } 38}

投稿2017/07/07 06:50

編集2017/07/07 07:08
kurokoba

総合スコア276

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_matsumoto

2017/07/07 08:09

回答ありがとうございます。 下記コードの(1)(2)について。 (1)はTreesetでセットした"A","B"をtypeAのforeachで出力している。 (2)はmapのvalueにあるTreesetに"C","D"をセットしてtypeBのmapのkeyを元にforeachし出力している。 今回理解できず悩んでいる点はcodes に//0000,0001,0002等が入っており、その値をresultCodesにaddしている。 しかしその処理でresultPool の方にも値が入っているということが分からず、悩んでおります。
kurokoba

2017/07/07 08:25

ちょっと今手が離せなくてちゃんと回答できないのですが、基本的に(2)とあまりかわりない話です。 質問のソースのresultCodesが 私のサンプルの"hs "にあたります。 すごく雑にいうとThreadLocalってスレッドIDがキーで、値が総称型(上の例だとTreeSet<String>)のMapみたいなものなので。
y_matsumoto

2017/07/07 08:45

ちょっと回答が分かりずらいと思ったため、追記します。 回答者さんが提示してくれた例文のケースと私が疑問に思っているケースの違いは 回答者さんのほうはTreeSetに設定した値をforEachで出力している 私のほうはListに格納されている値をforEachでTreeSetA(resultCodes)に設定していますが、 なぜかTreesetB(resultPool)にもTreeSetA(resultCodes)の内容が設定されています、 私はTreesetB(resultPool)にTreeSetA(resultCodes)の内容が設定されているということが理解できず悩んでおります。
y_matsumoto

2017/07/07 08:54

回答ありがとうございます。 ThreadLocalってスレッドIDがキーという認識ならresultPool.get()がkeyであり、valueがresultCodesということでしょうか。 そうするとvaluesに値が入ったからkeyであるresultPool.get()に値が入っているということで理解できます。この認識であっていますでしょうか。
kurokoba

2017/07/07 09:45

片手間回答ですみません...。ThreadLocalをMapに変えただけのこれはどうですか? ※いわるる参照渡しなのですが、そこが曖昧なら説明いたします。 protected Map<Integer,TreeSet<String>> resultPool = new HashMap<Integer,TreeSet<String>>(); static{ resultPool.put(123,new TreeSet<String>()); } protected void addResults(List<String> codes) { TreeSet<String> resultCodes = resultPool.get(123); codes.forEach(code -> { if (!resultCodes.contains(code)) { resultCodes.add(code); } }); }
kurokoba

2017/07/07 11:36

>ThreadLocalってスレッドIDがキーという認識ならresultPool.get()がkeyであり、valueがresultCodesということでしょうか。 言い回しだけの問題かもしれませんが、「valueがresultCodes」はあってるが「resultPool.get()がkeyであり」は違うかもしれない。 ThreadLocalクラスって内部にMapもっててThreadLocal#getをちょっとインチキな書き方すると class ThreadLocalモドキ<T>{ private Map<Object,T> map<key,value>; public T get(){ return map.get(スレッド固有の値); } } みたいな感じでしょうか。”スレッド固有の値”はThreadLocalクラス自身が知っているので外部から渡す必要が無い。だからThreadLocalのメソッドって”キーが無いMap”みたいになってる。
y_matsumoto

2017/07/10 00:10

mapと同じような認識でいましたが、認識が少しずれていたんですね。。 >。”スレッド固有の値”はThreadLocalクラス自身が知っているので外部から渡す必要が無い。だからThreadLocalのメソッドって”キーが無いMap”みたいになってる。 この説明でようやく今回よく分からなかった点が分かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問