2017-10-04 66 views
-1

假设我有一个像列表一样的列表;使用Java 8 Stream和Lambda我想从列表中形成一个特定的列表。详情如下

{ 
    {1-a12-abc,firstname,john}, 
    {2-a12-abc,firstname,tom}, 
    {1-a12-abc,lastname,doe}, 
    {3-a22-abc,city,Delhi} 
} 

我们可以把每个列表中包含一些PersonIdAttributeattribute value。我想每个Id,属性列表和相应的值列表一起。

使用Java 8个流API我想输出象下面这样:

{ 
     {{1-a12-abc},{firstname,lastname},{john,doe}}, 
     {{2-a12-abc},{firstname},{tom}}, 
     {{3-a22-abc},{city},{Delhi}} 
    } 

凡分组会随着每个列表的第一个元素上面给出。每个组的第二和第三个元素将形成列表。

请帮忙解决。

+0

看'Stream.map()','流.collect()','Collectors.groupingBy()'。当你卡住时,你可以回来问一些更详细的信息。但不要指望有人在没有显示任何努力的情况下为您提供完整的解决方案。 –

回答

1

这一个版本用java 8流:

// Initial list 
public class AttributeValue { 
    String id; 
    String attribute; 
    String attributeValue; 

    AttributeValue(String id, String attribute, String attributeValue) { 
     this.id = id; 
     this.attribute = attribute; 
     this.attributeValue = attributeValue; 
    } 

    @Override 
    public String toString() { 
     return "{" + id + "," + attribute + "," + attributeValue + "}"; 
    } 

    // ommiting equals() and hashCodes() methods for simplification 
} 

// final list 
public class Record { 
    String id; 
    List<String> attributes; 
    List<String> attributeValues; 

    Record(String id, List<String> attributes, List<String> attributeValues) { 
     this.id = id; 
     this.attributes = attributes; 
     this.attributeValues = attributeValues; 
    } 

    @Override 
    public String toString() { 
     return "{{" + id + "}," 
       + attributes.stream().collect(Collectors.joining(",", "{", "}")) + "," 
       + attributeValues.stream().collect(Collectors.joining(",", "{", "}")) + "}"; 
    } 

    // ommiting equals() and hashCodes() methods for simplification 
} 

private List<Record> transform(List<AttributeValue> values) { 
    return values.stream() 
      .collect(Collectors.groupingBy(value -> value.id, LinkedHashMap::new, Collectors.toList())) 
      .entrySet().stream() 
      .map(pair -> new Record(
       pair.getKey(), 
       pair.getValue().stream().map(value -> value.attribute).collect(Collectors.toList()), 
       pair.getValue().stream().map(value -> value.attributeValue).collect(Collectors.toList()) 
      )) 
      .collect(Collectors.toList()); 
} 

和单元测试使用junit5和assertj用于流利:

@Test 
void parse_a_van_page_with_empty_json_data() throws Exception { 
    List<AttributeValue> initial = Arrays.asList(
      new AttributeValue("1-a12-abc", "firstname", "john"), 
      new AttributeValue("2-a12-abc", "firstname", "tom"), 
      new AttributeValue("1-a12-abc", "lastname", "doe"), 
      new AttributeValue("3-a22-abc", "city", "Delhi") 
    ); 

    List<Record> expected = Arrays.asList(
      new Record("1-a12-abc", Arrays.asList("firstname", "lastname"), Arrays.asList("john", "doe")), 
      new Record("2-a12-abc", Collections.singletonList("firstname"), Collections.singletonList("tom")), 
      new Record("3-a22-abc", Collections.singletonList("city"), Collections.singletonList("Delhi")) 
    ); 

    assertThat(transform(initial)).containsAll(expected); 

    // Some printing 
    System.out.println("initial: "); 
    initial.forEach(System.out::println); 

    System.out.println("expected: "); 
    expected.forEach(System.out::println); 
} 
相关问题