• 締切済み

Collections.binarySearchについて

foxa-gogoの回答

  • foxa-gogo
  • ベストアンサー率44% (38/85)
回答No.4

>まず、 >indexedBinarySearchというのはどういうのタイミングで呼ばれますかね?? >もしlistはちゃんとソートされた場合もindexedBinarySearchが呼ばれるでしょうか。 #3の方が回答されたとおり、binarySearch()の中で渡されたリストがランダムアクセス可能かどうか調べ、可能であればこの関数、可能でなければ別の内部関数を呼んでいます。 >あと、 >>int cmp = compare(midVal, key); //compare("a","a") = 0(もしキ>ーがbならcompare("a","b")は負数を返し、low = mid+1 >これもよくわかりません、compareどういう動きなのかよくわかりません。 ここは実はソースをはしょって書いたのですが、本当は Comparable midVal = list.get(mid); int cmp = midVal.compareTo(key); となっています。 Stringオブジェクトは、インターフェースComparableを実装しており、これは「比較可能」という意味です。 インターフェースComparableのメソッドがcompareToで、Stringの場合、辞書順で自分のほうが若ければ負数を、後ろのほうであれば正の数を返します。 すなわち、"abc".compareTo("xyz")は負数を、逆は正の数を返します。 (とりあえず#3の方が回答されたとおりなのですが) list = { "One", "Three", "Two" }なので、アルファベット順にソートはされています。 さて、今回はStringのcompareToメソッドではなく、sortとして渡したComparatorを使うよう指定しています。 binarySearchではまず中央の値と、キーを比較します。なので、compare("Three", "Two")というふうにわたされますが、内部で"Two".compareTo("Three")となり、自分のほうが後ろなので、正の数を返します。 binarySearchは、正の数が帰ってきたので、探しているキーは、「"Three"よりも若いのだな」、と判断します。真ん中がlist[1]だったので、次はlist[0]と比較しますが、compareが"Two".compareTo("One")で、また正の数が返り、binarySearchは「キーはlist[0]よりもさらに若いのだな」と判断します。でももう0以上若い要素はないので、そこで検索終了、見つからなかったことになります。 Comparatorが期待するようにソートされていればよい(結果的にソートされていれば、明示的にソートする必要はない)ので、もしlist = { "Two", "Three", "One"}であったなら、見つかって0が返ったものと考えられます。(本当はmidValにキーよりも若いのか後ろなのか聞かなければいけないのに、キーにmidValよりも若いのかうしろなのか聞いているので、ちょうど反対となり、辞書順の反対に並んでいればComparatorが期待する順でソートされていることになります) ちなみに僕もJavaプログラマの試験勉強中です。。。重箱の隅をつつくような問題ばっかりで、嫌になっちゃいますねぇ。。。。。まぁ頑張りましょう!

関連するQ&A

  • StringクラスのcompareToメソッド

    ArrayListに登録した文字列を五十音順にソートしようと思いComparator を使用して 以下のようなサンプルプログラムを作ってみました。 ところが想定していたような {赤ちゃん、富士山、山口県}とはならず {富士山、山口県、赤ちゃん} というような結果になりました。 compare() の戻り値の部分を return ((String)arg1).compareTo((String)arg0); に変更しても{赤ちゃん、山口県、富士山} となり辞書の並びとは異なる結果になりました。 辞書順に並べるにはなにかよい方法はありますでしょうか。 public class compareTest { public static void main(String[] args) { ArrayList<String> array = new ArrayList<String>(); String a = "赤ちゃん"; String b = "山口県"; String c = "富士山"; array.add(a); array.add(b); array.add(c); for(int i=0;i<array.size();i++) { System.out.println("ソート前=" + array.get(i)); } Collections.sort(array, new testComp()); for(int i=0;i<array.size();i++) { System.out.println("ソート後=" + array.get(i)); } } } public class testComp implements Comparator { public int compare(Object arg0, Object arg1) { return ((String)arg0).compareTo((String)arg1); } }

    • ベストアンサー
    • Java
  • ArrayListのcloneメソッド

    お世話になります。 ArrayListのcloneメソッドなんですが、API上は「ArrayList のインスタンスのシャローコピーを返します。要素自体はコピーされません。 」と記載がありますが、 「ディープコピー」をしているような感じがして、なぜ「シャローコピー」と言っているのか、教えて欲しいです。 しかも、要素自体もコピーされているような…。 自分の理解では、 シャローコピー:コピー元、コピー先で同じオブジェクトを参照する ディープコピー:コピー元、コピー先で違うオブジェクトを参照する 試したソースは以下です。 --------------- import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList<String> array = new ArrayList<String>(); array.add("a"); array.add("b"); ArrayList<String> array2 = (ArrayList<String>) array.clone(); array2.add("c"); System.out.println("array:" + array); System.out.println("array2:" + array2); } } --------------- cloneメソッドはシャローコピーなので、array2で「c」がaddされたら、arrayも「c」が追加されて、 array:[a, b, c] array2:[a, b, c] となるはずが、 array:[a, b] array2:[a, b, c] となります。 array、array2は別々のオブジェクトを参照しているような気がします。 恐らく大きな勘違いをしているのかもしれませんが、 調べてもいまいち理解できませんでした。 お手数おかけしますが、よろしくお願い致します。

    • ベストアンサー
    • Java
  • Java初心者です。どうぞお教えください。

    CSVファイルを読み込んで、ソートしてから、現在日時のファイル名でCSVで書き出します。以下のファイルでは、CSVで書き出せません。現在日時のファイル名をつける方法もよくわかりません。どうぞ教えてください。importは省略しています。 public class CSVdata { public static void main(String[] args) { String fname = " " ; ArrayList<String> list = new ArrayList<String>(); String save_filename = getFileName(); if(args.length>0) { fname = args[0]; } try { BufferedReader reader = new BufferedReader( new FileReader(fname) ); String Line = null; while ((Line = reader.readLine()) != null) { list.add(Line); } reader.close(); Collections.sort(list ); PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(save_filename + ".csv"))); for (String string : list) { writer.println(string); } writer.close(); } catch (FileNotFoundException e) { System.out.println("ファイルがありません"); } catch (IOException e) { System.out.println("ファイルがありません"); } } public static String getFileName(){ Date d = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); return sdf.format(d); } }

  • binarySearchについて

    こんにちは、Javaを勉強しているものです。 binarySearchをしたとき、存在しない値を検索すると負の値が戻されると聞きましたが、その数値はどのようにして決められるのでしょうか? import java.util.*; class Sample { public static void main(String[] args){ String[] a ={"he", "is", "a", "boy"}; List<String> li = Arrays.asList(a); for(String s : a) System.out.print(S + ":"); System.out.println(); Collections.sort(li); for(String s: li) System.out.print(s + ":"); System.out.println(); System.out.println(Collections.binarySearch(li, "boy")); System.out.println(Collections.binarySearch(li, "girl")); Collections.reverse(li); for(String s: li) System.out.print(S + ":"); } } このコードの実行結果は、 he:is:a:boy: a:boy:he:is: 1 -3 is:he:boy:a: となります。 "girl"は、リストに存在しないので負の値である"-3"が返されたわけですが、3という数字がどのような理由で出てきたのか教えてください。 宜しくお願い致します。

  • 同期化時のことで

    いつもお世話になっています。 同期化を使用した場合のことで質問します。 private static final List<String> list = Collections.synchronizedList(new ArrayList<String>() ); を使いサーブレットでの同期化を実行しているのですが、 この場合に、値をソート化して処理を実行することは可能なのでしょうか? Collectionsを調べると、可能性としてsynchronizedSetだとできそうな気はするのですが、 その際の直列化の実装がよくわかりません。 考えているソースは以下です。 ** ラップオブジェクト同期化 **/ SortedSet sort = Collections.synchronizedSortedSet(new TreeSet<String>() ); /** サーブレットクラスでの処理 **/ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //リクエストデータ String key = request.getParameter("key"); //リクエストデータをSortedSetに格納する sort.add(key); //←この時点で、直列化のための何らかの処理がいる try{ //実行時、時間をずらすために宣言 Thread.sleep(1000); }catch(Exception e){ } //何の処理もしなかったら、実行された画面の順で処理が開始される synchronized(sort){ for(int a=0;a<10;a++){ System.out.println("a="+a); } } //SortedSetに格納された値の順 List sortList = new ArrayList(sort); for(int s=0;s<sortList.size();s++ ){ //↓すべての処理が終わってみたら、確かにソート化されているs System.out.println("sortList["+s+"]="+sortList.get(s)); } } jsp側のリクエストデータ 1回目 C 2回目 B 3回目 A 実行させたい順 C→A→B このとき、B,Aが渡されるタイミングは、Cの処理が実行中時 また、どのキーに対しての実行中なのかを見ることはできるのでしょうか? Collectionsクラスを見たところなさそうだったのですが。。。 宜しくお願いします。

    • ベストアンサー
    • Java
  • コレクションクラスについて

    ●下記のコードについて質問があります import java.util.*; public class Test { public static void main(String args[]) { ArrayList<ObjectOne> list = new ArrayList<ObjectOne>(); list.add(new ObjectOne()); list.add(new ObjectOne()); list.add(new ObjectOne()); Collections.sort(list); } } class ObjectOne { private int x = 0; private int y = 0; } このソースをコンパイルすると、 シンボル: メソッド sort(java.util.ArrayList<ObjectOne>) 場所 : java.util.Collections の クラス Collections.sort(list); と、エラーが表示されてしまいます。 java.util.*をインポートしているので、上記のようなエラーはでないと 思うのですが、うまくいかないです。おそらく、ObjectOneクラスで 何か処理漏れが起きているのかもしれませんが、エラーとなる原因を 特定することができません。 エラーとなる原因と解消する手立てを教えていただければと思っております。 宜しくお願い致します。 「追記」 ArrayList<ObjectOne> list = new ArrayList<ObjectOne>(); の<ObjectOne>を消せばエラーはなくなりますが、 <ObjectOne>を消さない方針で考えがあればと思っております。

  • Javaのプログラムについて教えてください!

    Genericsを使ってエラーの出ないようにするにはどうすればいいですか? import java.util.*; public class Sample{ public static void main(String[] args){ ArrayList ary = new ArrayList(); ary.add("Mac"); ary.add("Wiindows"); ary.add("Linux"); for(Object str:ary){ System.out.println((String)str); } } }

    • ベストアンサー
    • Java
  • 静止的フィールドについて教えてください

    教えてください。以下のプログラムだとして、 class Box { static int a = 0 ; int b = 0 ; int c = a+4; } class sample { public static void main(String[] args) { Box n = new Box() ; n.a-- ; n.b-- ; n.c[1]-- ; System.out.println("n.a= "+n.a);//-1 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2]="+n.c[2]);//4 Box m = new Box() ; m.a++ ; m.b++ ; m.c[2]++ ; System.out.println("n.a ="+n.a);//0 System.out.println("n.b ="+n.b);//-1 System.out.println("n.c[2] ="+n.c[2]);//4 System.out.println("m.a ="+m.a);//0 System.out.println("m.b ="+m.b);//1 System.out.println("m.c[2] ="+m.c[2]);//4 } } Box nの中のn.aの値はわかります。 ですが、Box mの中のn.aは、a がstaticフィールド(?)なので元の0に戻りますが、m.aがなぜ0なのかわかりません。 そもそもstatic int = ●; のときは、静止的intと教わったのですが、どういう現象が起こるのかいまいちです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • java iを1づつ増やすプログラムと2づつ増やすプログラム

    次のようにすればiを1づつ増やして表示されます。 class Calc{   int i=1;   int add(){     return i++;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 1 i = 2 i = 3 しかし次のように2づつ増やそうとすると、 class Calc{   int i=1;   int add(){     return i+2;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 3 i = 3 i = 3 このようになってしまいます。どこがおかしいのでしょうか?

    • ベストアンサー
    • Java
  • ArrayList の変数をaddしてもアドレスが変化しない

    windowsXP Eclipse3.4で import java.util.ArrayList; ArrayList list = new ArrayList(); Bean bean = new Bean(); list.add(bean); list.add(bean); System.out.println(bean); System.out.println(list); とアドレスを出力してみると beanのアドレスとlist内の二つのアドレスと3つのアドレスが すべて同じになってしまいます。 なにが原因か分からないのですが、分かる方がいましたら教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java