2016-05-15 6 views
0

私は全てがtoString()を上書きするオブジェクトの集合を持っています。 コンソールに書き出すか、文字列に連結して、基本的にはコレクションのためにtoString()を作成します。String.joinを使用するためにCharSequenceを実装していますか?

これを達成するためにforループを使用できます。仕事にSystem.out.println()について

import java.util.ArrayList; 

public class Foo 
{ 
    private double member; 

    public Foo() 
    { 
     member = Math.random(); 
    } 

    @Override 
    public String toString() 
    { 
     return "I'm foo " + member; 
    } 

    public static void main(String[] args) 
    { 
     ArrayList<Foo> foos = new ArrayList<>(); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 

     // print collection with loop 
     for (Foo foo : foos) 
     { 
      System.out.println(foo); 
     } 

     // print collection with String.join 
     System.out.println(String.join(System.lineSeparator(), foos)); // fails 
    } 
} 

toString()メソッドが呼び出され、:それは明示的なループを奪うためString.join()は、しかし非常に良く道のようです。インタフェースを明示的に実装する必要はありません。これは簡単で、普遍的な方法です。

しかし、String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)を動作させるには、単にtoString()メソッドを使用するだけでは不十分です。 Iterable<? extends CharSequence>が必要です。つまり、FooCharSequenceを実装する必要があります。

import java.util.ArrayList; 
import java.util.stream.IntStream; 

import java.lang.CharSequence; 

public class Foo implements CharSequence 
{ 
    private double member; 

    public Foo() 
    { 
     member = Math.random(); 
    } 

    @Override 
    public char charAt(int index) 
    { 
     return toString().charAt(index); 
    } 

    @Override 
    public IntStream chars() 
    { 
     return toString().chars(); 
    } 

    @Override 
    public IntStream codePoints() 
    { 
     return toString().codePoints(); 
    } 

    @Override 
    public int length() 
    { 
     return toString().length(); 
    } 

    @Override 
    public CharSequence subSequence(int start, int end) 
    { 
     return toString().subSequence(start, end); 
    } 

    @Override 
    public String toString() 
    { 
     return "I'm foo " + member; 
    } 

    public static void main(String[] args) 
    { 
     ArrayList<Foo> foos = new ArrayList<>(); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 
     foos.add(new Foo()); 

     System.out.println(String.join(System.lineSeparator(), foos)); 
    } 
} 

をしかし、これはにオブジェクトを変換する可能性を保証する以外、このような状況ではあまりやっていないコードのかなりのようだ:

は今、私はすぐにtoString()に委譲することで、そのインタフェースを実装しましたとにかくの形をしているStringである。

ソリューションに導入された定型句コードは、削除した定型句コードよりも大きいものです。

にはどうすればString.join()と素敵なクラスのプレーをすることができますか?

私はそのルートを行くとのインタフェースを実装するか、私はその場でいくつかの変換を実行する必要がありますでしょうか?たCharSequenceメソッドを呼び出すたびに新たのtoStringを呼び出すため

+0

あなたはdefaultをメソッドを実装する必要はありませんので、 '文字()'と 'コードポイントは、()'廃止されました。しかし、とにかく、この目的のために 'CharSequence'を実装することはまだ役に立たないので、受け入れられた答えにとどまります。 – Holger

答えて

3

使用状況に応じて、その経路は、非効率的であってもよいです。たとえば、メソッドが各文字を繰り返し処理しようとすると、あなたは深刻なパフォーマンスを見ているでしょう。 Java 8を使用しているので、なぜStreams APIを使用しないのですか?

System.out.println(foos.stream() 
     .map(Object::toString) 
     .collect(Collectors.joining(System.lineSeparator()))); 
+0

これもまた、パフォーマンスの面で改善できる迅速な実装でした。問題は、インターフェースを実装するために必要な定型コードです。 – null

+0

さて、はい、インターフェイスのすべてのメンバーを実装する必要があります。あなたは、Java 8で、いくつかのクラスのためにこれを行うために必要がある場合は、デフォルトの方法とC++のmixinのように行動することを目的に設計されたインタフェースを使用することができます。 –

+0

@JavierMartín:「抽象」メンバを実装するだけでよいので、質問の例は必要以上に多くの作業を行います。それでも、悪い業績の危険性についてのあなたの声明は成立しています。 – Holger

関連する問題