首页 > 解决方案 > 使用java将换行符分隔的JSON对象转换为JSON对象

问题描述

我必须将以下换行符分隔的 JSON 对象加载到 Dynamodb 表中。

{"car":0,"trip":0,"x":172,"y":43,"speed":10,"createdAt":"2019-01-01T21:47:10Z"}
{"car":0,"trip":0,"x":173,"y":44,"speed":15,"createdAt":"2019-01-01T21:48:10Z"}
{"car":0,"trip":0,"x":174,"y":45,"speed":20,"createdAt":"2019-01-01T21:49:10Z"}
{"car":0,"trip":1,"x":272,"y":53,"speed":20,"createdAt":"2019-01-02T21:57:10Z"}
{"car":0,"trip":1,"x":273,"y":54,"speed":25,"createdAt":"2019-01-02T21:58:10Z"}
{"car":0,"trip":1,"x":274,"y":55,"speed":30,"createdAt":"2019-01-02T21:59:10Z"}

car 和 trip 是唯一标识符。

如果我按顺序逐行加载上述对象,则唯一汽车和行程的最后一行将加载到 DynamoDB 表中。下表中的最终数据如下:

{"car":0,"trip":0,"x":174,"y":45,"speed":20,"createdAt":"2019-01-01T21:49:10Z"}
{"car":0,"trip":1,"x":274,"y":55,"speed":30,"createdAt":"2019-01-02T21:59:10Z"}

要求是以以下格式加载数据。

[
  {
   "car":0,
   "trip":0,
   "event": {
      "x": ["172","173","174"]
      "y": ["43","44","45"]
      "speed": ["10","15","20"]
      "createdAt": ["2019-01-01T21:47:10Z","2019-01-01T21:48:10Z","2019-01-01T21:49:10Z"]
     }
  },
  {
   "car":0,
   "trip":1,
   "event": {
      "x": ["272","273","274"]
      "y": ["53","54","55"]
      "speed": ["20","25","20"]
      "createdAt": ["2019-01-02T21:57:10Z","2019-01-02T21:58:10Z","2019-01-02T21:59:10Z"]
     }
  }
]

使用java以所需格式将给定的换行符分隔的JSON对象加载到DynamoDB中的最佳方法是什么?

标签: javajsonjackson

解决方案


您的输出结构与输入有些不同,因此仅将其添加到列表并转换为 JSON 并不能解决问题。您在 dynamo DB 中只看到 2 个条目的原因是我假设您正在制作一个复合键,car-trip因此只保存最后一个条目(不过我对 dynamo db 不太熟悉。我首先将所有条目保存到带有更多属性的复杂复合键(这更慢且效率不高)然后组合最终映射以生成输出。这是我尝试这样做的方法:

import com.google.gson.Gson;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Data
class CarTrip {
    private int car;
    private int trip;
    private int x;
    private int y;
    private int speed;
    private String createdAt;

    @Override
    public String toString() {
        return "CarTrip{" +
                "car=" + car +
                ", trip=" + trip +
                ", x=" + x +
                ", y=" + y +
                '}';
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class CarTripDynamoDb {
    private int car;
    private int trip;
    private CarTripEvent event;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class CarTripEvent {
    private List<String> x = new ArrayList<>();
    private List<String> y = new ArrayList<>();
    private List<String> speed = new ArrayList<>();
    private List<String> createdDates = new ArrayList<>();

    public void addX(String xItem) {
        x.add(xItem);
    }

    public void addY(String yItem) {
        y.add(yItem);
    }

    public void addSpeed(String speedItem) {
        speed.add(speedItem);
    }

    public void addCreatedDate(String createdDate) {
        this.createdDates.add(createdDate);
    }
}

public class SampleMain {
    public static void main(String[] args) throws IOException {
        final Gson gson = new Gson();
        //Reading and transforming to object
        List<CarTrip> carTrips = Files.readAllLines(Paths.get("data.json")).stream()
                .map(l -> gson.fromJson(l, CarTrip.class))
                .collect(Collectors.toList());

        //Create Map of composite keys and objecy
        Map<String, CarTrip> tripMap = new HashMap<>();
        for (CarTrip carTrip : carTrips) {
            final String key = generateMapKey(carTrip.getCar(), carTrip.getTrip(), carTrip.getX(), carTrip.getY(), carTrip.getSpeed());
            tripMap.put(key, carTrip);
        }

        // Create Output map
        Map<String, CarTripDynamoDb> tripDynamoDbMap = new HashMap<>();
        for (Map.Entry<String, CarTrip> entry : tripMap.entrySet()) {
            final CarTrip value = entry.getValue();
            final String newKey = "car-" + value.getCar() + "-trip-" + value.getTrip();
            if (tripDynamoDbMap.get(newKey) != null) {
                final CarTripDynamoDb carTripDynamoDb = tripDynamoDbMap.get(newKey);
                final CarTripEvent event = carTripDynamoDb.getEvent();
                updateEventFromTrips(value, event);
                carTripDynamoDb.setEvent(event);
                tripDynamoDbMap.put(newKey, carTripDynamoDb);
            } else {
                CarTripEvent event = new CarTripEvent();
                updateEventFromTrips(value, event);
                tripDynamoDbMap.put(newKey, new CarTripDynamoDb(value.getCar(), value.getTrip(), event));
            }
        }

        //Result
        List<CarTripDynamoDb> carTripEvents = tripDynamoDbMap.values().stream().collect(Collectors.toList());
        System.out.println(gson.toJson(carTripEvents));
    }

    private static void updateEventFromTrips(CarTrip value, CarTripEvent event) {
        event.addX(String.valueOf(value.getX()));
        event.addY(String.valueOf(value.getY()));
        event.addSpeed(String.valueOf(value.getSpeed()));
        event.addCreatedDate(value.getCreatedAt());
    }

    private static String generateMapKey(int... compositeIds) {
        final StringBuilder keyBuilder = new StringBuilder();
        for (int id : compositeIds) {
            keyBuilder.append(id).append("-");
        }
        return keyBuilder.toString();
    }

}


推荐阅读