2011-01-07 9 views
2

私はより慣用的なClojureで外部ライブラリをラップしようとしています。これには、データ構造を怠惰にすることも含まれます。私は以下のread静的メソッドを取得し、FooListを遅延させたいと思います。私は多くの問題に実行していますJava静的メソッド内のデータ構造を遅延させる方法を教えてください。

  1. Javaの静的メソッドが
  2. proxyを上書きすることができないだけでちょっとみかん動作しているようですが、私は海で迷子に
  3. gen-classオブジェクトのインスタンスを生成しているようです
  4. このメソッドでは、パブリックメソッドをオーバーライドすることを難しくしている別の静的およびプライベートメソッド(再利用したい)を呼び出します。

これを行うには最適な方法はありますか? FooListを開いて、それを怠け者として実装し、その結果のクラスを残りのコードで利用できるのでしょうか?

org.apache.commons.collections.list.LazyListは、タスクには適しているようですが、実際に使用する方法についてはわかりません。

ヘルプ?

public class Foo { 

    public static FooList read(String filename) { 
     FooList foos = new FooList(); //FooList extends ArrayList 
     BufferedReader br = new BufferedReader(new FileReader(filename)); 

     for (String s = br.readLine(); null != s; s = br.readLine()) { 
      Foo f = parseLine(s); 
      foos.add(f); 
     } 

     br.close(); 
     return foos; 
    } 

    private static Foo parseLine(String s) { 
     //return s as Foo 
    } 
} 

答えて

1

Clojureでは、Iterableコレクション(FooListなど)で(seqコレクション)を呼び出して、コレクションを横断する遅延シーケンスを取得できます。怠惰は実際にはあなたがJava側で完全なFoolListを既にロードしているので、実際にあなたに勝つことはありません。あなたが本当にClojureのとJavaの両方の間で怠惰をしたい場合は、次の操作を行うことができ

  • あなたのJava機能が するjava.util.Iteratorのカスタム実装ではなく、完全なコレクションを返してもらいます。 を怠惰な読み込みにするには、readLine()が(next()またはhasNext()メソッドの)繰り返しごとに1回だけ呼び出されるようにする必要があります。ファイルの最後に到達したら、リーダーを閉じる()ことを忘れないでください。Clojureの側で

  • (イテレータ-seqのJavaのイテレータ)と怠惰な配列を作成

あなたがこれを行う場合はClojureのシーケンスが消費されると、そのファイルが読み込まれると、増分解析されました。

+0

ありがとう、ちょうど私が探していたもの。 –

2

完全に範囲外であるかもしれませんが、私はsimilar problemでした。だから私の最終的な選択はjava.lang.Iterableといっていました。あなたが深く考えるなら、怠惰基準に正確に合っています。はい、それはいくつかのものを持っていませんList(例えばsize())、私は簡単にするためにこれを犠牲にする余裕があります。振り返ると、私はこの選択をしたことを後悔していない。

+0

私は同じことをします。単純に 'myFileIterator.next()'を呼び出して次の行を取得します。 IO例外をRuntimeExceptionまたはnull戻り値としてラップする。 – dagnelies

+0

実際に、私が 'FooList'をモンキーパッチすることができれば、私は単純に[clojure.lang.ISeq](https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq .java): 'first'、' rest'、 'more'、' cons'の実装を意味します。しかし、別のアイデアをありがとう。 –

1

Javaでは一般に、ファイル全体を読みたいので、これは価値がありません。しかし、ヘッダーだけを読んでみたいと思っていたり、一度に読むには大きすぎるファイルを読んだりするだけで、必要な行だけを読むことができます。

ただし、練習として、このクラスを変更する最も簡単な方法は、編集することです。このクラスのソースを取得することができます(逆コンパイルが必要な場合は逆コンパイル)し、クラスパスに最初に追加して、現在のシステムにパッチとして適用します。

+0

私が言ったように、私はライブラリを怠惰が望まれる慣用句に移植しています。私は自分自身でライブラリをコピーしておくことができると思うが、後で新しいバージョンなどで悲しみを感じるだろうと思う。 –

+0

@Pedro、そうだが、既存のライブラリをハックする必要がある解決策はおそらく悪い最良の解決策は、ライブラリのプロバイダに変更を依頼することです。 –

0

メソッドとFooとFooListに委譲し、BarとBarListを単純に使うように設計したいと思う遅延関数を使って、BarとBarListを作成することはできませんか?

質問に間違いはありませんでしたか?

+0

私は、外部のライブラリへの開発者のアクセス権を持たず、またパッチされたバージョンのコードを維持したくないという問題のクラスを猿にパッチしたいと思っています。 –

関連する問題