2017-01-17 26 views
0

Streams APIを使用して2つのマップのリストを結合する方法はありますか? のは、私が持っていないとしましょう:Java 8はマップの2つのリストを結合します

リスト#1

[ 
    { 
     id=1, attr1='a', attr2='b' 
    }, 
    { 
     id=2, attr1='c', attr2='d' 
    }, 
    { 
     id=3, attr1='e', attr2='f' 
    } 
] 

リスト#2

[ 
     { 
      id=1, attr3='x', attr4='y' 
     }, 
     { 
      id=2, attr3='x', attr4='z' 
     }, 
     { 
      id=3, attr3='z', attr4='y' 
     } 
    ] 

今私は(ちょうど参加SQLをリスト)キーIDによってこれらの2つのリストに参加したいと思います、 出力は次のようになります。

[ 
     { 
      id=1, attr1='a', attr2='b', attr3='x', attr4='y' 
     }, 
     { 
      id=2, attr1='c', attr2='d', attr3='x', attr4='z' 
     }, 
     { 
      id=3, attr1='e', attr2='f', attr3='z', attr4='y' 
     } 
    ] 

どうもありがとう!

+3

を使用しましたかこれはコード作成サービスではありません。 – marstran

+1

これはJavascriptとよく似ていますが、それは疑似コードに過ぎません。 :)しかし、マップは実際のJavaコードでどのように見えますか?私は 'id'が鍵だと思いますが、最初のリストにある' attrib1'と 'attrib2'は何ですか?値オブジェクトの属性?ネストされたコレクション内の要素 – Thomas

+0

java 8でコレクションの連結を行うことができます。[this](http://stackoverflow.com/questions/4896662/combine-multiple-collections-into-a-single-logical-collection/23998250#23998250)を参照してください。あなたの問題のためにそれを試してください。 –

答えて

0

ストリームの有無にかかわらず、さまざまな方法があります。最良の方法は、あなたが私たちに与えていないより正確な入力要件に依存します。以下は、あなたの質問に例のリストのために働くでしょう:

if (list1.size() != list2.size()) { 
     throw new IllegalStateException("Lists don’t match, not same size"); 
    } 

    List<Map<String, Character>> comnbinedList = IntStream.range(0, list1.size()) 
      .mapToObj(i -> { 
        Map<String, Character> m1 = list1.get(i); 
        Character id1 = m1.get("id"); 
        Map<String, Character> m2 = list2.get(i); 
        Character id2 = m1.get("id"); 
        if (! id1.equals(id2)) { 
         throw new IllegalStateException("Lists don’t match, id " + id1 + " != " + id2); 
        } 
        HashMap<String, Character> mergedMap = new HashMap<>(m1); 
        mergedMap.putAll(m2); 
        return mergedMap; 
       }) 
      .collect(Collectors.toList()); 

を結果は次のとおりです。

[{id=1, attr2=b, attr1=a, attr4=y, attr3=x}, {id=2, attr2=d, attr1=c, attr4=z, attr3=x}, {id=3, attr2=f, attr1=e, attr4=y, attr3=z}] 

あなたはもちろん、"id"定数を宣言することになるでしょう。

0

マップ内のIDキーを使用するデータ構造。これは少し異例ですが、ここではストリームコレクターの例です。あなたのマップ値がintString両方あるので、私はあなたが何をしようとしたのですか?Map<String, Object>

import java.util.*; 
public class JoinTwoListofMaps { 
    public static void main(String... args){ 
     List<Map<String, Object>> list1 = new ArrayList<>(); 
     List<Map<String, Object>> list2 = new ArrayList<>(); 
     Map<String, Object> map1_1 = new HashMap<>(); 
      map1_1.put("id",1); 
      map1_1.put("attr1","a"); 
      map1_1.put("attr2","b"); 
     list1.add(map1_1); 
     Map<String, Object> map2_1 = new HashMap<>(); 
      map2_1.put("id",1); 
      map2_1.put("attr3","x"); 
      map2_1.put("attr4","y"); 
     list2.add(map2_1); 
     System.out.println(joinTwoListOfMaps(list1, list2)); 
    } 
    @SafeVarargs 
    public static List<Map<String, Object>> joinTwoListOfMaps(List<Map<String, Object>>... listsOfMaps){ 
     List<Map<String, Object>> finalList = Arrays.stream(listsOfMaps).collect(ArrayList::new, List::addAll, List::addAll); 
     return finalList.stream().collect(ArrayList::new, (list, mapToMerge) ->{ 
      Optional<Map<String, Object>> mapWithSameID = list.stream() 
        .filter(map -> map.get("id").equals(mapToMerge.get("id"))).findFirst(); 
      if (mapWithSameID.isPresent()) mapWithSameID.get().putAll(mapToMerge); 
      else list.add(mapToMerge); 
     }, ArrayList::addAll); 
    } 
} 
関連する問題