gpt4 book ai didi

java - 将 Java List 转换为 Pivot 格式

转载 作者:行者123 更新时间:2023-11-29 08:25:25 31 4
gpt4 key购买 nike

我有一个下面的类,想用 java 将数据对象列表转换为数据透视表格式。

public class Data {

private String consultedOn;
private String consultedBy;

// Getters

// Setters


}


List<Data> reports = new ArrayList<Data>();

reports.add(new Data("04/12/2018","Mr.Bob"));
reports.add(new Data("04/12/2018","Mr.Jhon"));
reports.add(new Data("04/12/2018","Mr.Bob"));
reports.add(new Data("05/12/2018","Mr.Jhon"));
reports.add(new Data("06/12/2018","Mr.Bob"));
reports.add(new Data("06/12/2018","Mr.Jhon"));
reports.add(new Data("07/12/2018","Mr.Bob"));

我想在集合中用 java 将上面的列表转换成下面的表格格式。

consultedOn       Mr.Bob          Mr.Jhon  
---------------------------------------
04/12/2018 2 1
05/12/2018 0 1
06/12/2018 1 1
07/12/2018 1 0

请注意,consultedOn 字段不限于两个值,该字段可以包含任何数据,因此集合应该是动态的。

我尝试通过以下代码使用 Java8 流。

class DataMap {


private String consultedOn;
private String consultedBy;

public DataMap(String consultedOn) {
super();
this.consultedOn = consultedOn;
}

public DataMap(String consultedOn, String consultedBy) {
super();
this.consultedOn = consultedOn;
this.consultedBy = consultedBy;
}


public String getConsultedOn() {
return consultedOn;
}


public void setConsultedOn(String consultedOn) {
this.consultedOn = consultedOn;
}


public String getConsultedBy() {
return consultedBy;
}


public void setConsultedBy(String consultedBy) {
this.consultedBy = consultedBy;
}


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((consultedOn == null) ? 0 : consultedOn.hashCode());
return result;
}


@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof DataMap ))
return false;
DataMap other = (DataMap )obj;
if (consultedOn == null) {
if (other.consultedOn != null)
return false;
} else if (!consultedOn.equals(other.consultedOn))
return false;
return true;
}


}


Map<DataMap, List<DataReport>> map = reports.stream()
.collect(Collectors.groupingBy(x -> new DataMap(x.getConsultedOn(), x.getConsultedBy())));

但是 map 并没有按照我的预期给出预期的结果。

我不确定如何继续处理此类数据,我们将不胜感激。

最佳答案

这是一个完整的答案,使用我在评论中解释的技术,即设计一个类 Row 代表您要为每一行生成的内容,即 consultedOn 字符串,以及每个人的咨询次数。

public class Pivot {
private static final class Data {

private final String consultedOn;
private final String consultedBy;

public Data(String consultedOn, String consultedBy) {
this.consultedOn = consultedOn;
this.consultedBy = consultedBy;
}

public String getConsultedOn() {
return consultedOn;
}

public String getConsultedBy() {
return consultedBy;
}
}

private static final class Row {
private final String consultedOn;
private final Map<String, Integer> consultationsByPerson = new HashMap<>();

public Row(String consultedOn) {
this.consultedOn = consultedOn;
}

public void addPerson(String person) {
consultationsByPerson.merge(person, 1, Integer::sum);
}

public int getConsultationsFor(String person) {
return consultationsByPerson.getOrDefault(person, 0);
}

public String getConsultedOn() {
return consultedOn;
}
}

private static class PivotReport {

private final Map<String, Row> rowsByConsultedOn = new HashMap<>();
private SortedSet<String> persons = new TreeSet<>();

private PivotReport() {}

private void addData(Data d) {
rowsByConsultedOn.computeIfAbsent(d.getConsultedOn(), Row::new).addPerson(d.getConsultedBy());
persons.add(d.consultedBy);
}

public static PivotReport create(List<Data> list) {
PivotReport report = new PivotReport();
list.forEach(report::addData);
return report;
}

public String toString() {
String headers = "Consulted on\t" + String.join("\t", persons);
String rows = rowsByConsultedOn.values()
.stream()
.sorted(Comparator.comparing(Row::getConsultedOn))
.map(this::rowToString)
.collect(Collectors.joining("\n"));
return headers + "\n" + rows;
}

private String rowToString(Row row) {
return row.getConsultedOn() + "\t" +
persons.stream()
.map(person -> Integer.toString(row.getConsultationsFor(person)))
.collect(Collectors.joining("\t"));
}
}


public static void main(String[] args) {
List<Data> list = createListOfData();
PivotReport report = PivotReport.create(list);
System.out.println(report);
}

private static List<Data> createListOfData() {
List<Data> reports = new ArrayList<Data>();

reports.add(new Data("04/12/2018","Mr.Bob"));
reports.add(new Data("04/12/2018","Mr.Jhon"));
reports.add(new Data("04/12/2018","Mr.Bob"));
reports.add(new Data("05/12/2018","Mr.Jhon"));
reports.add(new Data("06/12/2018","Mr.Bob"));
reports.add(new Data("06/12/2018","Mr.Jhon"));
reports.add(new Data("07/12/2018","Mr.Bob"));
reports.add(new Data("07/12/2018","Mr.Smith"));

return reports;
}
}

请注意,由于您对 consultedOn 字段使用的是 String 而不是 LocalDate,因此日期将按字典顺序排序,而不是按时间顺序排序。您应该使用适当的类型:LocalDate。

关于java - 将 Java List 转换为 Pivot 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53682421/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com