Home > OS >  Java streams: return results to custom object
Java streams: return results to custom object

Time:01-19

I have a piece of code that has list of objects as follows.

List<PivotMapEgModel> pivotMapList = List.of(new PivotMapEgModel(1L, "1"), new PivotMapEgModel(1L, "2"), new PivotMapEgModel(1L, "3"), new PivotMapEgModel(2L, "5"));

It is guaranteed that there will always be a maximum of 3 codes per value.

I have a class that looks like this:

@Data
@AllArgsConstructor
class ResultSet {
    long value;
    String code_1;
    String code_2;
    String code_3;
}

I am currently doing the stream operation in this way:

pivotMapList.stream().collect(Collectors.groupingBy(PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList())))

This is producing the output in the following way: {1=[1, 2, 3], 2=[5]}

I need to perform stream operations on the pivotMapList to get the output to show in List<ResultSet> as follows:

[{value=1, code_1=1, code_2=2, code_3=3},
 {value=2, code_1=1, code_2=null, code_3=null}]

I am not sure how I can get List<ResultSet> from stream operations

Any help to achieve the desired output would be greatly appreciated! Thank you

CodePudding user response:

You have already mapped value to its codes. You can just continue by streaming the entry set of the resulting map and map entries to ResultSet.

List<ResultSet> result = pivotMapList.stream()
            .collect(Collectors.groupingBy(PivotMapEgModel::getValue, Collectors.mapping(PivotMapEgModel::getCode, Collectors.toList())))
            .entrySet()
            .stream()
            .map(entry -> new ResultSet(entry.getKey(), getCode(entry.getValue(), 0), getCode(entry.getValue(), 1), getCode(entry.getValue(), 2)))
            .collect(Collectors.toList());

getCode() is simple method taking care not to get exception when retrieving values from the list.

private static String getCode(List<String> codes, int index) {
  if (index >= codes.size()) {
    return null;
  }
  return codes.get(index);
}

CodePudding user response:

Here is one way.

class ResultSet {

    long value;
    String code_1;
    String code_2;
    String code_3;

    public ResultSet(long value, String code_1,String code_2, String code_3) {
        this.value = value;
        this.code_1 = code_1;
        this.code_2 = code_2;
        this.code_3 = code_3;
    }
    
    public String toString() {
        return "{%d, %s, %s, %s}".formatted(value, code_1, code_2, code_3);
    }
}

Use your existing map to build the list. Stream the entrySet of the map and use map to instantiate a ResultSet instance. The forloop will fill the list with nulls if it isn't fully populated.


List<ResultSet> resultSet = map.entrySet().stream()
        .<ResultSet>map(ent-> {
            List<String> lst = ent.getValue();
            for( int i = lst.size(); i < 3; i  ) {
                lst.add(null);
            }
            return new ResultSet(ent.getKey(), lst.get(0),
                    lst.get(1), lst.get(2));
        }).toList();


resultSet.forEach(System.out::println);

prints

{1, 1, 2, 3}
{2, 5, null, null}

Note that you could simply stream the existing entrySet from the original map to combine the process, returning the desired List<ResultSet>

  • Related