2016-12-01 14 views
2

私は、コレクタインタフェースを実装し、そのメソッドをオーバーライドしてカスタムコレクタを実装しました。コレクターの実装は次のとおりです。Java 8ストリーム - カスタムコレクタを使用する場合のNullPointerException

class MyCustomCollector implements Collector<Person, StringJoiner, String>{ 

    @Override 
    public Supplier<StringJoiner> supplier() { 
     // TODO Auto-generated method stub 
     return() -> new StringJoiner("|"); 
    } 

    @Override 
    public BiConsumer<StringJoiner, Person> accumulator() { 
     // TODO Auto-generated method stub 
     return (joiner,person) -> joiner.add(person.name.toUpperCase()); 
    } 

    @Override 
    public BinaryOperator<StringJoiner> combiner() { 
     // TODO Auto-generated method stub 
     return (joiner1, joiner2) -> joiner1.merge(joiner2); 
    } 

    @Override 
    public Function<StringJoiner, String> finisher() { 
     // TODO Auto-generated method stub 
     return StringJoiner::toString; 
    } 

    @Override 
    public Set<java.util.stream.Collector.Characteristics> characteristics() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 

はここに私のPersonクラスである:ここで

class Person implements Comparable<Object>{ 
    String name; 
    int age; 

    Person(String name, int age) { 
     this.name = name; 
     this.age = age; 
    } 

    @Override 
    public String toString() { 
     return name; 
    } 

    public int compareTo(Object obj){ 
     int returnValue; 
     if(age ==((Person) obj).age) 
      returnValue=0; 
     else 
      if(age >((Person) obj).age) 
       returnValue = 1; 
      else 
       returnValue =-1; 

     return returnValue; 
    } 

    public boolean equals(Object obj) 
    { 
     if(!(obj instanceof Person)) 
      return false; 

     return (age == ((Person) obj).age); 
    } 

    public int hashCode() 
    { 
     return name.hashCode(); 
    } 

} 

そして、私の呼び出し文である...

List<Person> persons = 
     Arrays.asList(
      new Person("Max", 18), 
      new Person("Peter", 23), 
      new Person("Pamela", 23), 
      new Person("David", 12), 
      new Person("Pam", 23)); 
String names2 = persons.stream() 
      .collect(new MyCustomCollector()); 

上記のステートメントが実行されます

、私は次のようにNullPointerExceptionを取得しました:

スレッド "main"の例外java.lang.NullPointerException java.util.stream.ReduceOps $ 3.getOpFlags(ReduceOps.java:185) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) java.util.stream.ReferencePipeline.collectでcom.my.j8.TestStreams.mainで(ReferencePipeline.java:499) (TestStreams.java:231)

私は間違いを犯していた場合、誰もが言うことができます?ここで

+2

ヒント:あなたのプログラムで 'null'を探すことから始めます。 –

+0

GhostCat私はまったくそれをしなかった。 – KayV

+0

クイックフィードバックをありがとう! – GhostCat

答えて

6

public Set<java.util.stream.Collector.Characteristics> characteristics() { 
    return null; 

戻る代わりにnullをセット

private final static Set<Characteristics> EMPTY = Collections.emptySet(); 

...

return EMPTY; 

か、単に

return Collections.emptySet(); 

(コレクションクラスとしてすでに独自にいくつかのEMPTY定数を持っている)などがあります。

コアポイントは次のとおりです。このインターフェイスにはこのメソッドが含まれています。 「この部分を使用していません」では、依然としてその方法を「合理的に」実行する必要があります。したがって、将来のためにそれを念頭に置いてください。コレクションを返すインターフェイスでは、が空ののものを返すことで「コンテンツなし」と言われます。 nullの代わりに!

もちろん、問題は周囲のフレームワークによって確認できます。このメソッドがnullを返すかどうかを確認します。しかし、言ったように:あなたが何らかのコレクションを扱っているときには、ヌルの使用についてはを忘れてしまいます。何もない場合は、空のコレクションオブジェクトを作成してください!

NPEを避けるための重要なステップの1つはで、最初はが返されません。

そして、それを超えた

:ユージンが指摘されるように - あなたはおそらく、本当に慎重にあなたが 本当にがここに空のSetで行くべきかのチェックしたいです。言い換えれば、あなたは Characteristicsを見て、彼らの全体の概念を理解していますか?あなたはここで "none"をしたいと100%確信していますか?

+0

これで問題は解決しました。しかし、私は、特性を使用していない、なぜ私は特性からいくつかの空のセットを返す必要がありますか? – KayV

+1

私の更新された回答を参照してください。その答えが役に立ったので、受け入れを検討してください。 – GhostCat

+1

@GhostCatあなたは本当にこれを慎重に考えてから特性を提供してはいけません。これらを基にして内部的に実行される最適化にはさまざまなものがありますが、それらを壊す可能性はありません。 – Eugene

関連する問題