我有一个使用场景,在那里我会爬取一些数据,对于某些记录,一些键具有多个值。我最终想要的输出是CSV格式,我有一个库可以做到这一点,并且它需要一个二维数组。
所以我的输入结构看起来像是
我编写了一个通用的转换,它基于所有记录中的最大值数量计算每个键的列数,并为具有小于最大值的记录留下空单元格,但结果比预期更复杂。
我的问题是:它能否以更简洁/有效(但仍然通用)的方式编写?特别是使用Java 8流/lambda等?
以下是示例数据和我的算法(尚未测试超出示例数据):
所以我的输入结构看起来像是
List<TreeMap<String, List<String>>>
(我使用TreeMap
确保键的顺序稳定),我的输出需要是String[][]
。我编写了一个通用的转换,它基于所有记录中的最大值数量计算每个键的列数,并为具有小于最大值的记录留下空单元格,但结果比预期更复杂。
我的问题是:它能否以更简洁/有效(但仍然通用)的方式编写?特别是使用Java 8流/lambda等?
以下是示例数据和我的算法(尚未测试超出示例数据):
package org.example.import;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<TreeMap<String, List<String>>> rows = new ArrayList<>();
TreeMap<String, List<String>> row1 = new TreeMap<>();
row1.put("Title", Arrays.asList("Product 1"));
row1.put("Category", Arrays.asList("Wireless", "Sensor"));
row1.put("Price",Arrays.asList("20"));
rows.add(row1);
TreeMap<String, List<String>> row2 = new TreeMap<>();
row2.put("Title", Arrays.asList("Product 2"));
row2.put("Category", Arrays.asList("Sensor"));
row2.put("Price",Arrays.asList("35"));
rows.add(row2);
TreeMap<String, List<String>> row3 = new TreeMap<>();
row3.put("Title", Arrays.asList("Product 3"));
row3.put("Price",Arrays.asList("15"));
rows.add(row3);
System.out.println("Input:");
System.out.println(rows);
System.out.println("Output:");
System.out.println(Arrays.deepToString(multiValueListsToArray(rows)));
}
public static String[][] multiValueListsToArray(List<TreeMap<String, List<String>>> rows)
{
Map<String, IntSummaryStatistics> colWidths = rows.
stream().
flatMap(m -> m.entrySet().stream()).
collect(Collectors.groupingBy(e -> e.getKey(), Collectors.summarizingInt(e -> e.getValue().size())));
Long tableWidth = colWidths.values().stream().mapToLong(IntSummaryStatistics::getMax).sum();
String[][] array = new String[rows.size()][tableWidth.intValue()];
Iterator<TreeMap<String, List<String>>> rowIt = rows.iterator(); // iterate rows
int rowIdx = 0;
while (rowIt.hasNext())
{
TreeMap<String, List<String>> row = rowIt.next();
Iterator<String> colIt = colWidths.keySet().iterator(); // iterate columns
int cellIdx = 0;
while (colIt.hasNext())
{
String col = colIt.next();
long colWidth = colWidths.get(col).getMax();
for (int i = 0; i < colWidth; i++) // iterate cells within column
if (row.containsKey(col) && row.get(col).size() > i)
array[rowIdx][cellIdx + i] = row.get(col).get(i);
cellIdx += colWidth;
}
rowIdx++;
}
return array;
}
}
程序输出:
Input:
[{Category=[Wireless, Sensor], Price=[20], Title=[Product 1]}, {Category=[Sensor], Price=[35], Title=[Product 2]}, {Price=[15], Title=[Product 3]}]
Output:
[[Wireless, Sensor, 20, Product 1], [Sensor, null, 35, Product 2], [null, null, 15, Product 3]]
String[][]
? - MC EmperorObject[][]
。 - Martynas Jusevičius