我需要生成这样的输出json
{
"account": {
"Alpha": {
"OLD": {
"long": "zerozerooneO",
"short": "001O"
},
"NEW": {
"long": "zerozerooneN",
"short": "001N"
}
}
}
}
来自以下示例的对象列表
[
{
"codetype":"Alpha",
"shortOldCode":"001O",
"longOldCode":"zerozerooneO",
"shortNewCode":"001N",
"longNewCode":"zerozerooneN"
},
{
"codetype":"Beta",
"shortOldCode":"001O",
"longOldCode":"zerozerooneO",
"shortNewCode":"001N",
"longNewCode":"zerozerooneN"
}
]
我尝试过这样的事情
Map<String, Map<String, Map<String, List<Object>>>> newList = new HashMap<>();
newList = dataMap.stream()
.filter(distinctByKey(code -> code.getCodeType())).collect(
groupingBy((GetCodeTypes a) -> "account",
groupingBy((GetCodeTypes b) -> b.getCodeType(),
groupingBy((GetCodeTypes c) -> "OLD",
mapping(
v -> {
GetCodeTypesResponse.Old
oldCode = new GetCodeTypesResponse.Old();
oldCode.setLongs(v.getLongOldCode());
oldCode.setShorts(v.getShortOldCode());
return oldCode;
}, toList())))));
希望任何人都可以为我指明正确的方向,以使用 hashmap 获得所需的输出
这是一个合理的,但非基于流的解决方案来解决您的问题:
package com.learn.grouping;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* This is the format of your input JSON
*/
@Getter
@Setter
@ToString(doNotUseGetters = true)
public class BlamItemInput
{
@JsonProperty("codetype")
private String codeType;
private String longNewCode;
private String longOldCode;
private String shortNewCode;
private String shortOldCode;
}
package com.learn.grouping;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
/**
* This converts from input format to desired output (layered map) format.
*/
@Component
public class BlamConverter
{
public CodeTypeMap convert(final List<BlamItemInput> blamItemInputList)
{
final CodeTypeMap returnValue;
if (CollectionUtils.isNotEmpty(blamItemInputList))
{
returnValue = new CodeTypeMap();
for (final BlamItemInput current : blamItemInputList)
{
final KapowItem kapowItem = new KapowItem();
kapowItem.setNewItem(current.getLongNewCode(), current.getShortNewCode());
kapowItem.setOldItem(current.getLongOldCode(), current.getShortOldCode());
returnValue.addKapowItem(current.getCodeType(), kapowItem);
}
}
else
{
returnValue = null;
}
return returnValue;
}
}
package com.learn.grouping;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.ToString;
/**
* Top level of the output format
*/
@Getter
@ToString(doNotUseGetters = true)
public class CodeTypeMap
{
@JsonProperty("account")
private final Map<String, KapowItem> kapowMap = new HashMap<>();
public void addKapowItem(
final String keyValue,
final KapowItem newCodeTypeItem)
{
kapowMap.put(keyValue, newCodeTypeItem);
}
}
package com.learn.grouping;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Getter;
import lombok.ToString;
/**
* Second level of the output JSON
*/
@Getter
@ToString(doNotUseGetters = true)
@JsonPropertyOrder({"OLD", "NEW"})
public class KapowItem
{
@JsonProperty("NEW")
private KapowNestedItem newItem;
@JsonProperty("OLD")
private KapowNestedItem oldItem;
public void setNewItem(
final String longValue,
final String shortValue)
{
newItem = new KapowNestedItem(longValue, shortValue);
}
public void setOldItem(
final String longValue,
final String shortValue)
{
oldItem = new KapowNestedItem(longValue, shortValue);
}
}
package com.learn.grouping;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
/**
* Bottom (third) level of the output JSON
*/
@Getter
@RequiredArgsConstructor
@ToString(doNotUseGetters = true)
public class KapowNestedItem
{
@JsonProperty("long")
private final String longValue;
@JsonProperty("short")
private final String shortValue;
}
package com.learn.grouping;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Converter unit test because, you aren't done until after you unit test.
*/
@ExtendWith(MockitoExtension.class)
public class TestBlamConverter
{
private static final String INPUT_JSON = "[{\"codetype\":\"Alpha\",\"shortOldCode\":\"001O\",\"longOldCode\":\"zerozerooneO\",\"shortNewCode\":\"001N\",\"longNewCode\":\"zerozerooneN\"},{\"codetype\":\"Beta\",\"shortOldCode\":\"001O\",\"longOldCode\":\"zerozerooneO\",\"shortNewCode\":\"001N\",\"longNewCode\":\"zerozerooneN\"}]";
private BlamConverter classToTest;
private ObjectMapper objectMapper;
@BeforeEach
void beforeEach()
{
final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
SerializationFeature.FAIL_ON_EMPTY_BEANS);
builder.serializationInclusion(Include.NON_NULL);
objectMapper = builder.build();
classToTest = new BlamConverter();
}
@Test
void convert_allGood_succes() throws JsonMappingException, JsonProcessingException
{
final CodeTypeMap actualResult;
final List<BlamItemInput> inputList;
final String outputJson;
final TypeFactory typeFactory = objectMapper.getTypeFactory();
inputList = objectMapper.readValue(INPUT_JSON, typeFactory.constructCollectionType(List.class, BlamItemInput.class));
actualResult = classToTest.convert(inputList);
outputJson = objectMapper.writeValueAsString(actualResult);
System.out.println("outputJson: " + outputJson);
}
}