Assuming ObjectMapper
is from the Jackson library, I think you should be able to create only one instance of it as it's safe to do so safe to do so. Pro-tip: on that link, the developer of Jackson also suggests using ObjectReader
/ObjectWriter
if you are using Jackson 2.x.
Assuming ObjectMapper
is from the Jackson library, I think you should be able to create only one instance of it as it's safe to do so. Pro-tip: on that link, the developer of Jackson also suggests using ObjectReader
/ObjectWriter
if you are using Jackson 2.x.
Assuming ObjectMapper
is from the Jackson library, I think you should be able to create only one instance of it as it's safe to do so. Pro-tip: on that link, the developer of Jackson also suggests using ObjectReader
/ObjectWriter
if you are using Jackson 2.x.
Since you have 1300 columns, performing a Map.get(Object)
twice to retrieve the value for each column, per row, is not going to be the fastest way to do so. Just hold on to that thought for a moment...
Will it not be better off to create one CSV file per product type, so that the consumers of these data can fully process the product-type-specific file they require, instead of having to cherry-pick columns from a 40 MB file, which will likely be slower as well?
Writing output (cont'd)
Resuming from the earlier section, Java 8 has a [Map.getOrDefault(Object, V)
] 6 method that simplifies your approach of calling Map.get(Object)
twice:
// String value = map.get(header) == null ? "" : map.get(header).replace(",", "");
String value = map.getOrDefault(header, "").replace(",", "");
The conversion of a List<LinkedHashMap<String, String>
to a List<String>
is relatively straightforward when you think of the approach as such:
Create a map of the total columns you have, with elements mapping to themselves, and treat this as the zeroth row, i.e. a single-element
List<Map<String, String>>
.Create a stream out of the zeroth row and your actual payload (\1ドル...n\$ rows), so that you can apply the common step of mapping each column header against all the \$n + 1\$
Map
s and concatenating them as aString
.
Putting it altogether:
private static List<String> flattenAll(List<LinkedHashMap<String, String>> input) {
Set<String> columns = input.stream()
.flatMap(v -> v.keySet().stream())
.collect(Collectors.toCollection(LinkedHashSet::new));
Map<String, String> header = columns.stream()
.collect(Collectors.toMap(k -> k, v -> v));
return Stream.concat(Stream.of(header), input.stream())
.map(m -> columns.stream()
.map(k -> m.getOrDefault(k, "").replace(",", ""))
.collect(Collectors.joining(",")))
.collect(Collectors.toList());
}
How we get our columns
is similar to your original approach but done with a stream-based approach, i.e. to flatMap()
each Map.keySet()
into a Stream<String>
, before collect()
-ing them into a LinkedHashSet
.
Since you have 1300 columns, performing a Map.get()
to retrieve the value for each column, per row, is not going to be the fastest way to do so. Just hold on to that thought for a moment...
Will it not be better off to create one CSV file per product type, so that the consumers of these data can fully process the product-type-specific file they require, instead of having to cherry-pick columns from a 40 MB file, which will likely be slower as well?
Since you have 1300 columns, performing a Map.get(Object)
twice to retrieve the value for each column, per row, is not going to be the fastest way to do so. Just hold on to that thought for a moment...
Will it not be better off to create one CSV file per product type, so that the consumers of these data can fully process the product-type-specific file they require, instead of having to cherry-pick columns from a 40 MB file, which will likely be slower as well?
Writing output (cont'd)
Resuming from the earlier section, Java 8 has a [Map.getOrDefault(Object, V)
] 6 method that simplifies your approach of calling Map.get(Object)
twice:
// String value = map.get(header) == null ? "" : map.get(header).replace(",", "");
String value = map.getOrDefault(header, "").replace(",", "");
The conversion of a List<LinkedHashMap<String, String>
to a List<String>
is relatively straightforward when you think of the approach as such:
Create a map of the total columns you have, with elements mapping to themselves, and treat this as the zeroth row, i.e. a single-element
List<Map<String, String>>
.Create a stream out of the zeroth row and your actual payload (\1ドル...n\$ rows), so that you can apply the common step of mapping each column header against all the \$n + 1\$
Map
s and concatenating them as aString
.
Putting it altogether:
private static List<String> flattenAll(List<LinkedHashMap<String, String>> input) {
Set<String> columns = input.stream()
.flatMap(v -> v.keySet().stream())
.collect(Collectors.toCollection(LinkedHashSet::new));
Map<String, String> header = columns.stream()
.collect(Collectors.toMap(k -> k, v -> v));
return Stream.concat(Stream.of(header), input.stream())
.map(m -> columns.stream()
.map(k -> m.getOrDefault(k, "").replace(",", ""))
.collect(Collectors.joining(",")))
.collect(Collectors.toList());
}
How we get our columns
is similar to your original approach but done with a stream-based approach, i.e. to flatMap()
each Map.keySet()
into a Stream<String>
, before collect()
-ing them into a LinkedHashSet
.
I suppose the output will resemble something the following, if we can sort the rows by product type and there are no other overlapping columns other than the ID and product type:
I suppose the output will resemble something the following, if we can sort the rows by product type:
I suppose the output will resemble something the following, if we can sort the rows by product type and there are no other overlapping columns other than the ID and product type: