2017-10-14 9 views
1

私は、Android Studioでの作業、およびFirebaseから以下のデータを取得しています: "キー" はFirebaseデータを取得した後にHashMapをループするにはどうすればいいですか?

public void initialiseColourSet(ValueEventListener listener) { 

    if(this.key == null) return; 

DatabaseReference mColourSetReference = FirebaseDatabase.getInstance().getReference() 
     .child("coloursets").child(this.key); 

mColourSetReference.addListenerForSingleValueEvent(listener); 

}

coloursets: 
    default: 
     name: "Default colour set" 
     description: "Default set of colours" 
     colours: 
      white: 
      red: 255 
      green: 255 
      blue: 255 
      name: "white" 
      black: 
      red: 0 
      green: 0 
      blue: 0 
      name: "black" 

は、私はこのようにそれを取得しています「デフォルト」に設定され、「リスナー」は:

new ValueEventListener() { 

    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     ArrayList<ChartColour> colourList= new ArrayList<>(); 
     Map<String, HashMap> objectMap = (HashMap<String, HashMap>) dataSnapshot.getValue(); 

     // SOMETHING NEEDS TO GO HERE - SEE BELOW 

     } 

} 

ColourSetクラスha以下の(S)

String key, name, description; 
ArrayList<ChartColour> colours = new ArrayList<>(); 

だから、私はcolourSetの名前と説明を取得して、それから「色を設定するために使用されるローカル変数colourList、に色のリストを取得するには「のObjectMap」をループにしたいです'をColourSetオブジェクトに追加します。

リスナーで正しいループを取得できません。私は多くの答えを見てきましたが、私の場合にはあてはまりません。

現在、私は、リスナーに次き:

だから、
new ValueEventListener() { 

    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
    ArrayList<ChartColour> colourList= new ArrayList<>(); 
    Map<String, HashMap> objectMap = (HashMap<String, HashMap>) dataSnapshot.getValue(); 
    for (Map.Entry<String, HashMap> entry : objectMap.entrySet()) { 
     switch (entry.getKey()) { 
     case "name": 
      mColourSet.setName(String.valueOf(entry.getValue())); 
      break; 
     case "description": 
      mColourSet.setDescription(String.valueOf(entry.getValue())); 
      break; 
     case "colours": 
      // Need some kind of FOR LOOP here 
      ChartColour colour = new ChartColour(); 
      /* 
       colour.setKey(??); 
       colour.setName(??); 
       colour.setRed(??); 
        ... etc ... */ 
       colourList.add(colour); 
      // END OF FOR LOOP 
      mColourSet.setColours(colourList); 
     } 
    } 
    } 
}); 

、私はちょうど私が色をループするために、リスナーにFORループに入れるために必要なものはよく分かりません。私がこれまでに試したことは、何が間違っているのか説明しなくても、揺れる赤い線を私に与えるだけです。

誰も私に助言できますか?何か助けてくれてありがとう。

+1

赤い線がどこにあるのか分かりませんが、外部マップの値型として 'HashMap'がジェネリック型を設定していないため、キーと値の両方が' Object'に解決されます。 。 – Dave

+0

ありがとうございます。 objectMapを意味しますか?彼らは何に設定すべきですか? – Sharon

+1

'Map 'の意味で、 'HashMap'部分は型パラメータを指定していないので、' HashMap 'に効果的です。この場合、 'HashMap 'である必要があると思います。それはあなたのコード内のいくつかの赤い線に簡単に寄与することができますが、どこにエラーがあるのか​​分からずに私は確信できません。私はまだコードを実行しようとしていない... – Dave

答えて

1

あなたのコードを見るのに少し時間がかかりましたが、私は外見にはいくつか気づいています。

最初にValueEventListenerを実装しようとすると、実装する必要がある別の方法があります。コードバージョンに多少の違いがあるかもしれませんが、修正するのは簡単な点の1つかもしれません。

@Override 
public void onCancelled(DatabaseError error) { } 

第二に、dataSnapshot.getValue()の戻り値のためのあなたのタイプのキャストは正しいことはできません。サンプルデータは、データがMap<String, HashMap>であるという概念と一致しません。 「名前」と「説明」の項目は、ではなく、HashMapではありません。私はそれが実行時に失敗すると思います。 Map<String, ?>にキャストする可能性が高くなります。その時点から、各エントリ値の期待値をコードに伝えなければなりません。StringまたはMapまたはIntegerのいずれかのキーに応じて可変になります。未チェックのキャストがあることを示すために、発生した場所、私は場所で@SupressWarnings("unchecked")を追加した

@Override 
public void onDataChange(DataSnapshot dataSnapshot) { 
    @SuppressWarnings("unchecked") 
    Map<String, ?> defaultColourSet = (Map<String, ?>)dataSnapshot.getValue(); 
    if (defaultColourSet == null) { 
     /* log a warning, DataSnapshot.getValue may return null */ 
     return; 
    } 
    List<ChartColour> colourList= new ArrayList<>(); 
    for (Map.Entry<String, ?> colorSetEntry : defaultColourSet.entrySet()) { 
     switch (colorSetEntry.getKey()) { 
      case "name": 
       mColourSet.setName((String)colorSetEntry.getValue()); 
       break; 
      case "description": 
       mColourSet.setDescription((String)colorSetEntry.getValue()); 
       break; 
      case "colours": 
       @SuppressWarnings("unchecked") 
       Map<String, ?> colourMap = (HashMap<String, ?>)colorSetEntry.getValue(); 
       for (Map.Entry<String, ?> colourEntry : colourMap.entrySet()) { 
        @SuppressWarnings("unchecked") 
        Map<String, ?> colourValueMap = (Map<String, ?>)colourEntry.getValue(); 
        ChartColour colour = new ChartColour(); 
        // Note that the following calls are based on assumption... 
        colour.setName((String)colourValueMap.get("name")); 
        colour.setRed((Integer)colourValueMap.get("red")); 
        colour.setGreen((Integer)colourValueMap.get("green")); 
        colour.setBlue((Integer)colourValueMap.get("blue")); 
        colourList.add(colour); 
       } 
       mColourSet.setColours(colourList); 
       break; 
     } 
    } 
} 

:私はあなたのonDataChange方法がどのように見えるかの推測をハザードがあった場合、それは次のようになります(あなたのサンプルデータで通知)キャストは、コンパイラが利用できない知識に基づいて安全です。 JSONデータのレイアウトによって厳密に通知されます。特にデータが変更された場合は、実行時に障害が発生する可能性があります。 ClassCastExceptionを処理するtry-catchのような、より堅牢なエラー処理を追加することをお勧めします。

+0

ありがとう!はい、私はOnCancelledを持っています、ちょうどスペースを節約するためにここに入れなかった - 謝罪、私はそれを明確にしておくべきです。 – Sharon

+0

私は残りの部分をチェックし、どうやったらどうなるかを見ていきます。助けてくれてありがとう。 – Sharon

+0

ありがとうございます!これは物事をはるかに明確にしました。私はそれを置くことができると気付かなかったのですか?マップの定義で - 私はHashMapを使用しようとしていて、必要なものにキャストしようとしていましたが、それは明らかに動作しませんでした。私は今エラー処理に取り組んでいます - ただ最初に働くことを望んでいました。あなたの助けをもう一度ありがとう! – Sharon

関連する問題