Javaの独自のデリゲートについて

このQ&Aのポイント
  • Javaにおいて独自のデリゲートを使用する際のコードの書き方について解説します。
  • ラムダ式がJavaに導入される可能性についても触れながら、コードの書き方を検討するタイミングについて考えましょう。
  • 今の段階では、ラムダ式がまだ導入されていないため、独自のデリゲートを活用する場合には特定の書き方をする必要があります。
回答を見る
  • ベストアンサー

ラムダ式とかデリゲートっぽい感じのことについて

色々と調べてみたのですが 現状ではC#における List<int> ml = new List<int>(); ml.Add(111); ml.Add(121); ml.Add(310); Console.WriteLine(ml.Exists(t=>{ return t == 310;} )); 的なことをやろうとすると、一応このまんま「単純にあるかどうかとかだけ」なら final Collection<Integer> ml = new ArrayList<Integer>(); ml.add(111); ml.add(121); ml.add(310); System.out.println(ml.contains(310)); でも可能ですが、 独自のクラスで独自のデリゲートっぽい事をやろうとすると 例えば interface Func<T, R> { R Do(T t1); } class MyList<T>{ private List<T> list = new ArrayList<T>(); public boolean Exists( final Func<T,Boolean> deleg ){ for(T i : list) if ( deleg.Do(i) ) return true; return false; } public boolean add(T t){ return list.add(t); } } ////どっかの関数で///// final MyList<Integer> ml = new MyList<Integer>(); ml.add(111); ml.add(121); ml.add(310); //匿名クラスを作り、Doをオーバーライド final boolean b = ml.Exists( new Func<Integer,Boolean>(){ @Override public Boolean Do(Integer t1){ return t1.equals(310); }}); System.out.println(b); これぐらいの内容になってしまう と思うのですが( とくに面倒なのが、「new Func」からの、「同じ型の表記」が複数回登場してしまう ) だいたい今タイムリーにこの辺が改善されるかどうか というくらいのとこに行ってる感じで Java 7ではラムダ式が先送りになったみたいだけど 近々JavaでもC#(やC++11)っぽく出来るようになる可能性が高め なので、今からコードを書く場合には こういうところが絡む部分はまだ様子見しといて 採用された後でラムダ式を使って簡単に書こう と、いう判断にしといても良さ気ですかね?

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

Java SE 8のリリースは来年の夏らしいけど、 それまで待つとなると、ずいぶんと長期的なスケジュールになりますね。 まず、そんな長期スケジュールで問題ないのかということ。 あと、開発中にVMのメジャーバージョンが変わるとなると、 コーディング済みの部分も修正が入るんじゃないかとか、 そっちの方が心配です。

LongSecret
質問者

お礼

どうもどうも ご回答ありがとうございます♪ >Java SE 8のリリースは来年の夏らしいけど、 それまで待つとなると、ずいぶんと長期的なスケジュールになりますね。 そこですよねw 実は質問投稿完了するまでは時期知らなかったのですが 「あれまてよ、次っていつなんだろう?」 って思って私も調べてみて 「これは長いなぁw」 と思ってた次第です。 今直接的にJavaのプログラムを作らないといけない理由はないのですが おそらくほぼ、数ヵ月以内に作る必要が生じそう で、しかし現在製作中のC++での超本格アプリと比べると その「必要とされるプログラムの規模」は結構小さくて済むと思うのと 端から端まで自分で管轄できることが予想されるため とりあえずはJava 7にあわせて(こういう手法は出来るだけ最小限になるように)書いといて 8がリリースされたら 気の向いた部分を気の向いたときに 修正する という風にするのが現実的に思います。 しかし、ちょっと疑問が生じました。 上記のようにJava 7でこういう事やろうとした場合 final int num___ = 310; //匿名クラスを作り、Doをオーバーライド final boolean b = ml.Exists( new Func<Integer,Boolean>(){ @Override public Boolean Do(Integer t1){ return t1.equals(num___); }}); こんな風に「finalなローカル変数」だと、匿名(やインナー)クラスで表記上使える (というより、「使えてほしいと思ってなかったのに、ほんとは使えてしまう」) と思うんですが なぜこうなるかというと http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1042755330 のように、コンパイラが内部的にコピーを行っているからって事のようなんですが 「インナークラスで使ってないfinalなローカル変数」は 「勝手にコピーされることはない」 のでしょうか? 可読性のためにローカル変数を固定してるだけなのに、勝手にコピーが出来ちゃうとしたら 非常に厄介なのですが んなこたぁない、かな…?

LongSecret
質問者

補足

まだしばらく先になりそうなので しばらく様子見で問題なさそうですが、流石に後一年はまだ長いかな でも進展がないのでいったん締め切ることにします。(5/26) ありがとうございました。

関連するQ&A

  • ArrayList::getメソッドは何で不便に作られている?

    ArrayList::getメソッドはObject型を返却しますよね。 そのため、たとえば、  ArrayList list = new ArrayList();  Integer aaa = new Integer();  list.add(aaa);  Integer aaa2 = (Integer)list.get(0); のように、Integerでリストに追加したものを取り出すのに わざわざIntegerでキャストしなければなりません。 なんで、こんな不便な仕様になっているのでしょうか?

    • ベストアンサー
    • Java
  • ArrayListのイテレータについて

    java初心者です. 以下のようなプログラム(かなり簡略化しています)で ArrayList<Integer> list =new ArrayList<Integer>(); list.add(new Integer(1)); Iterator it = list.iterator(); while(it.hasNext()){ it.next() if(Math.random()<0.5) list.add(new Integer(2));//50%の確率で"2"を追加 }; arraylistの「先頭からイテレータを使って呼び出していくのと同時に,後ろに50%の確率で"2"を追加していきたい」のですが, うまく動作しません.「」の中のような動作を行うには,どうすればいいでしょうか? よろしくお願いします.

  • Javaのプログラムの質問です。

    Javaのプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。  注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{  private int Count;  private String Data[];  private Iterator ite;  private ListIterator lite;  // コンストラクタ  void mylist(){   Data = new String[10];   Count = 0;  }  (1)  public boolean add(Object str){   if(Count >= 10){    return false;   }   Data[Count ++] = new String((String)str);   return true;  }  public void add(int i,Object str){  }        public boolean addAll(Collection c){   return false;  }        public boolean addAll(int i,Collection c){   return false;  }    (2)  public void clear(){   Count = 0;  }  public boolean contains(Object str){   return false;  }          public boolean containsAll(Collection c){   return false;  }  public boolean equals(Object str){   return false;  }    (3)  public Object get(int i){   return (i >= Count);  }  public int hashCode(){   return -1;  }  public int indexOf(Object str){   return -1;  }  public boolean isEmpty(){   return false;  }  public Iterator iterator(){   return ite;  }     public int lastIndexOf(Object str){   return -1;  }     public ListIterator listIterator(){   return lite;  }     public ListIterator listIterator(int i){   return lite;  }    (4)  public Object remove(int i){   return (i >= Count);  }    public boolean remove(Object str){   return true;  }         public boolean removeAll(Collection c){   return false;  }         public boolean retainAll(Collection c){   return false;  }    (5)  public Object set(int i,Object str){   return Data[i];  }    (6)  public int size(){   return Count;  }  public List subList(int i,int j){   return this;  }  public Object[] toArray(){   return Data;  }  public Object[] toArray(Object[] a){   return Data;  } } class Main {  public static void main(String[] args) {   mylist sub = new mylist();   sub.add("ビルドバーニングガンダム");   sub.add("ライトニングガンダム");   sub.add("ウイニングガンダム");   sub.add("ガンダムフェニーチェリナーシタ");   sub.add("R・ギャギャ");   for(int i = 0; i < sub.size(); i++){      System.out.println(sub.get(i));   }   // 改行   System.out.println();   // setメソッド   sub.set(1,"ガンダムエピオン");   for(int i = 0; i < sub.size(); i++){    System.out.println(sub.get(i));   }   // 改行   System.out.println();   // sizeメソッド   System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n");   // removeメソッド   sub.remove(1);   for(int i = 0; i < sub.size(); i++){       System.out.println(sub.get(i));   }   // clearメソッド   sub.clear();   System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです");    } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。

  • 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
  • ArrayList で配列を扱う場合の記述方法について

    ArrayList で配列を扱う場合の記述方法について、 探しきれないのでご教授お願いします。 ArrayList list = new ArrayList(); list.add("AAA"); list.add("BBB"); list.add("CCC"); for (int i = 0; i < list.size(); i++) { System.out.println(i+"は"+list.get(i)); } という箇所をArrayList<Date>listを使って書き直すのはどのようになるでしょうか。 ArrayList<Date>list= new ArrayList<Date>(); list.add("AAA"); list.add("BBB"); list.add("CCC"); for (int i = 0; i < list.size(); i++) { System.out.println(i+"は"+list.get(i)); } とすると、 型 ArrayList<Date> のメソッド add(Date) は引数 (String) に適用できません。 というエラーになってしまいました。

    • ベストアンサー
    • Java
  • エラーを解決したいんですが。

    // Genericsを用いたArrayListを使用し // ループ処理にはiteratorを使用しない。 // for文を使ってリスト中身が奇数の場合はそのまま画面表示。 // 偶数の場合は-1をかけてから画面表示。 import java.util.ArrayList; class Test{ public static void main(String[] args) { //GenericsのInteger型でArrayListのインスタンスを生成 ArrayList<Integer> array = new ArrayList<Integer>(); array.add(1); array.add(2); array.add(3); array.add(4); array.add(5); for(int i=0; i<array.size(); i++) { Integer integer = array.get( i ); //もし値が偶数だったら if(integer % 2 == 0){ integer *= -1; System.out.println( integer ); } //(それ以外)もし値が奇数だったら else{ System.out.println( integer ); } } } } 上記のプログラムで、 >Integer integer = array.get( i ); の場所が、「交換性がない型」と言われ、エラーになってしまうんですが どうしたらいいですか?

    • ベストアンサー
    • Java
  • このプログラムが実行できません。

    スタックの動きを再現するプログラムを作ったのですが、エラーがでます。プログラムは以下に示します。 メインクラス public class mainStack { public static void main(String[] args) { StackTest stack=new StackTest(); stack.push("AAAAA"); stack.push("BBBBB"); } } スタックのクラス import java.util.ArrayList; @SuppressWarnings("unchecked") public class StackTest implements Stack { ArrayList list=new ArrayList(); public int AA=0; public boolean empty() { if(list.isEmpty()==true){ return true; } else{ return false; } } public void pop() { list.remove(AA); AA--; } public void push(String element) { list.add(element); AA++; } public void top(){ System.out.println(list.get(AA)); } } 何故かlist.add()のところにエラーが出てしまいます。是非分かる方解答お願いします。

    • ベストアンサー
    • Java
  • ソートについて

    以下のプログラムを実行すると整数のソート結果が "1","12","3"となってしまいます。 整数と文字列を分離させてそれぞれソートさせたいのですが 方法がわかりません。 import java.util.*; import java.io.*; class StrArray{ ArrayList list = new ArrayList(); //最下行に要素を追加 public void add(String data){ list.add(data); } //全ての要素を配列で所得 public String[] getAll(){ String[] all = new String[list.size()]; for(int i=0; i<list.size(); i++){ all[i] = super.get(i); } return all; } public static final int ASC_SORT = 0; public void sort(int mode){ ArrayList al = this.qsort(mode, list); al = list; } //クイックソート public ArrayList qsort(int mode, ArrayList data){ ArrayList result = new ArrayList(); if(data.size()<1){ return new ArrayList(); } String middle = (String)data.get(data.size()/2); ArrayList left = new ArrayList(); ArrayList right = new ArrayList(); for(int i=0; i<data.size(); i++){ if(i != data.size()/2){ if(mode == 0){ if(((String)data.get(i)).compareTo(middle)<=0){ left.add(data.get(i)); } else{ right.add(data.get(i)); } result.addAll(qsort(0, left)); result.add(middle); result.addAll(qsort(0, right)); return result; } return result; } } } } class Sample{ public static void main(String args[]){ StrArray alist = new StrArray(); alist.add("bbb"); alist.add("aaa"); alist.add("ddd"); alist.add("ccc"); alist.add("3"); alist.add("1"); alist.add("12"); alist.sort(0); String[] info = alist.getAll(); for(int i = 0; i < info.length; i++){ System.out.println(info[i]); } } }

  • Itaratorから値を取得するには?

    ArrayList<String> list = new ArrayList<String>(); list.add("その1"); list.add("その2"); list.add("その3"); list.add("その4"); Itarator itar = list.itarator(); while(itar.hasNext()){ System.out.println(itar.toString); itar.Next(); } 上記のように記述するとコンソールには その1 その2 その3 その4 というように出力されることを期待したのですが 結果はitar自身の値が返ってきてしまいました。 Itaratorを使用して、ArrayListの値を出力させるには どうすればよいのでしょうか?

    • ベストアンサー
    • Java
  • ArrayListにArrayListを用いた場合の対応について

    public static ArrayList<Integer> f1 = new ArrayList<Integer>(); public static ArrayList<ArrayList> f2 = new ArrayList<ArrayList>(); public void parse(Context ct){   if(ct.match("f")){ ct.nextToken(); while(ct.currentToken() != null && ct.currentToken().matches("[0-9]+/[0-9]*/[0-9]+")){ f1.add(ct.fToken(ct.currentToken())); ct.nextToken(); } f2.add(f1); f1.clear(); System.out.println(f2); 例f⇒f 1/4/3 2/5/6 4/5/6  1行⇒[1,2,4]  1/3/5 7/1/2 8/3/4  2行⇒[1,7,8]         ・         ・         ・   回答例⇒[[1,2,4],[1,7,8],[…],…,[…]] 上記のようなobj形式のf行をそれぞれ1行ごとに頭文字を取り出して(Contextで)、f1=ArrayList<Integer>にaddしていき、1行を読み終わったらf1=ArrayList<Integer>をf2=ArrayList<ArrayList>にaddしていき、最終的には回答例のような形にしたいです。 私はf1にaddした数字をf2にf1をaddして、その後f1をclearしてその空いたf1にまた次の行の数字をaddさせるつもりだったのですが、f1をクリアしてしまうと一度f2にaddしたはずのものも消えてしまうことに気づきました。 どのように改造すれば回答例のようにf2のArrayListにf1のArrayListをいくつもいれて表示することができますか。 教えてください。

専門家に質問してみよう