在 Java 中的对象中拆分数组
Split Array in Objects in Java
我一直在将一个数组拆分为一个对象的子数组。我有以下内容:
Input/Output A类:
{
attribute1: 'value1',
attribute2: 'value2',
// etc.
assets: [
{assetAttribute1: 'value1', // etc.},
{assetAttribute2: 'value2', // etc.}
// etc.
]
}
流输入:
inputs = [
{
attribute1: 'value1',
attribute2: 'value2',
assets: [
{assetAttribute1: 'value1', // etc.},
{assetAttribute2: 'value2', // etc.}
// etc.
]
},
]
预期流输出:
outputs = [
{
attribute1: 'value1', // same as from the input
attribute2: 'value2', // same as from the input
assets: [
{assetAttribute1: 'value1', // etc.} // input asset array index 0
]
},
{
attribute1: 'value1', // same as from the input
attribute2: 'value2', // same as from the input
assets: [
{assetAttribute2: 'value2', // etc.} // // input asset array index 1
]
},
]
代码:
KStream<String, AClass> inputs = //...
KStream<String, AClass> output = inputs.map((key, aclass) -> {
return aclass.getAssets().stream().map(asset -> {
AClass transform = new AClass();
transform = aclass.clone();
transform.setAssets(Arrays.asList(asset));
return new KeyValue<String, AClass>(key, miaTransitAsset);
});
});
如您所见,这是行不通的。但我现在不知道如何使用 Java Streams 实现这一目标。你可以忽略kafka流,因为它基本上是一样的。
感谢您的帮助!
然而,用一个流来完成它是可以管理的,为了便于阅读,让我分开这个拳头:
为简单起见,我自己创建了一个 class(希望从 JSON 描述中得到它):
class Input {
String attribute1;
String attribute2;
List<Map<String, String>> assets;
public Input(String attribute1, String attribute2, List<Map<String, String>> assets) {
this.attribute1 = attribute1;
this.attribute2 = attribute2;
this.assets = assets;
}
}
然后进行一些愚蠢的初始化以处理一些数据:
List<Map<String, String>> assets = new ArrayList<>();
Map<String, String> attributeMap1 = new HashMap<>();
Map<String, String> attributeMap2 = new HashMap<>();
attributeMap1.put("assetAttribute1", "value1");
attributeMap2.put("assetAttribute2", "value2");
assets.add(attributeMap1);
assets.add(attributeMap2);
Input input = new Input("value1", "value2", assets);
List<Input> inputs = Arrays.asList(input);
lambdas 来了:
首先,您必须获取要提取的所有属性(您将在其上创建新对象的资产列表):
List<Map<String, String>> extractedAssets = inputs
.stream()
.map(e -> e.assets)
.flatMap(Collection::stream)
.collect(Collectors.toList());
那么对于这些资产中的每一个,您都需要一份您之前输入的内容的副本,但“资产”列表内容有所不同。所以最好的方法是为每个以前提取的资产创建一个新对象:
List<Input> collect = extractedAssets.stream()
.map(e -> new Input(
input.attribute1,
input.attribute2,
Collections.singletonList(e)))
.collect(Collectors.toList());
这应该有效:)
或者使用一个流:
List<Input> collect1 = inputs.
stream()
.map(e -> e.assets)
.flatMap(Collection::stream)
.map(e -> new Input(
inputs.get(0).attribute1,
inputs.get(0).attribute2,
Collections.singletonList(e)))
.collect(Collectors.toList());
感谢您的帮助 Przemysław Gęsieniec。你启发了我从另一个方向思考,我想我现在找到了一个方法:
KStream<String, AClass> output = inputs.flatMap(
(key,value) -> {
List<KeyValue<String, AClass>> result = new ArrayList<>();
value.getAssets().forEach(asset -> {
AClass transform = value.clone();
transform.setAssets(Arrays.asList(asset));
result.add(KeyValue.pair(key, transform));
});
return result;
});
我一直在将一个数组拆分为一个对象的子数组。我有以下内容:
Input/Output A类:
{
attribute1: 'value1',
attribute2: 'value2',
// etc.
assets: [
{assetAttribute1: 'value1', // etc.},
{assetAttribute2: 'value2', // etc.}
// etc.
]
}
流输入:
inputs = [
{
attribute1: 'value1',
attribute2: 'value2',
assets: [
{assetAttribute1: 'value1', // etc.},
{assetAttribute2: 'value2', // etc.}
// etc.
]
},
]
预期流输出:
outputs = [
{
attribute1: 'value1', // same as from the input
attribute2: 'value2', // same as from the input
assets: [
{assetAttribute1: 'value1', // etc.} // input asset array index 0
]
},
{
attribute1: 'value1', // same as from the input
attribute2: 'value2', // same as from the input
assets: [
{assetAttribute2: 'value2', // etc.} // // input asset array index 1
]
},
]
代码:
KStream<String, AClass> inputs = //...
KStream<String, AClass> output = inputs.map((key, aclass) -> {
return aclass.getAssets().stream().map(asset -> {
AClass transform = new AClass();
transform = aclass.clone();
transform.setAssets(Arrays.asList(asset));
return new KeyValue<String, AClass>(key, miaTransitAsset);
});
});
如您所见,这是行不通的。但我现在不知道如何使用 Java Streams 实现这一目标。你可以忽略kafka流,因为它基本上是一样的。
感谢您的帮助!
然而,用一个流来完成它是可以管理的,为了便于阅读,让我分开这个拳头:
为简单起见,我自己创建了一个 class(希望从 JSON 描述中得到它):
class Input {
String attribute1;
String attribute2;
List<Map<String, String>> assets;
public Input(String attribute1, String attribute2, List<Map<String, String>> assets) {
this.attribute1 = attribute1;
this.attribute2 = attribute2;
this.assets = assets;
}
}
然后进行一些愚蠢的初始化以处理一些数据:
List<Map<String, String>> assets = new ArrayList<>();
Map<String, String> attributeMap1 = new HashMap<>();
Map<String, String> attributeMap2 = new HashMap<>();
attributeMap1.put("assetAttribute1", "value1");
attributeMap2.put("assetAttribute2", "value2");
assets.add(attributeMap1);
assets.add(attributeMap2);
Input input = new Input("value1", "value2", assets);
List<Input> inputs = Arrays.asList(input);
lambdas 来了:
首先,您必须获取要提取的所有属性(您将在其上创建新对象的资产列表):
List<Map<String, String>> extractedAssets = inputs
.stream()
.map(e -> e.assets)
.flatMap(Collection::stream)
.collect(Collectors.toList());
那么对于这些资产中的每一个,您都需要一份您之前输入的内容的副本,但“资产”列表内容有所不同。所以最好的方法是为每个以前提取的资产创建一个新对象:
List<Input> collect = extractedAssets.stream()
.map(e -> new Input(
input.attribute1,
input.attribute2,
Collections.singletonList(e)))
.collect(Collectors.toList());
这应该有效:)
或者使用一个流:
List<Input> collect1 = inputs.
stream()
.map(e -> e.assets)
.flatMap(Collection::stream)
.map(e -> new Input(
inputs.get(0).attribute1,
inputs.get(0).attribute2,
Collections.singletonList(e)))
.collect(Collectors.toList());
感谢您的帮助 Przemysław Gęsieniec。你启发了我从另一个方向思考,我想我现在找到了一个方法:
KStream<String, AClass> output = inputs.flatMap(
(key,value) -> {
List<KeyValue<String, AClass>> result = new ArrayList<>();
value.getAssets().forEach(asset -> {
AClass transform = value.clone();
transform.setAssets(Arrays.asList(asset));
result.add(KeyValue.pair(key, transform));
});
return result;
});