Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Java列表转换为Pivot格式_Java_Data Structures_Java 8_Java Stream - Fatal编程技术网

将Java列表转换为Pivot格式

将Java列表转换为Pivot格式,java,data-structures,java-8,java-stream,Java,Data Structures,Java 8,Java Stream,我有一个下面的类,希望用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.

我有一个下面的类,希望用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"));
请注意,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())));
类数据映射{
私人字符串咨询;
私人字符串咨询人;
公共数据映射(字符串参考){
超级();
this.consultedOn=consultedOn;
}
公共数据映射(字符串consultedOn、字符串consultedBy){
超级();
this.consultedOn=consultedOn;
this.consultedBy=consultedBy;
}
公共字符串getConsultedOn(){
回访咨询;
}
公共void setConsultedOn(字符串consultedOn){
this.consultedOn=consultedOn;
}
公共字符串getConsultedBy(){
返回咨询人;
}
公共void setConsultedBy(字符串consultedBy){
this.consultedBy=consultedBy;
}
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
result=prime*result+((consultedOn==null)?0:consultedOn.hashCode();
返回结果;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(!(数据映射的obj实例))
返回false;
DataMap other=(DataMap)obj;
if(consultedOn==null){
if(other.consultedOn!=null)
返回false;
}else如果(!consultedOn.equals(other.consultedOn))
返回false;
返回true;
}
}
Map=reports.stream()
.collect(Collectors.groupingBy(x->newdatamap(x.getConsultedOn(),x.getConsultedBy()));
但是地图并没有按照我的期望给出预期的结果


我不知道如何处理这类数据,如果有任何帮助,我们将不胜感激。

这里有一个完整的答案,使用我在评论中解释的技巧,即设计一个类
,表示您希望为每一行生成的内容,即
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、字符串consultedBy){
this.consultedOn=consultedOn;
this.consultedBy=consultedBy;
}
公共字符串getConsultedOn(){
回访咨询;
}
公共字符串getConsultedBy(){
返回咨询人;
}
}
私有静态最终类行{
私人最终字符串咨询;
private final Map consultationsByPerson=new HashMap();
公用行(字符串参考){
this.consultedOn=consultedOn;
}
公共人员(字符串人员){
merge(person,1,Integer::sum);
}
public int GetConsultationfor(字符串人){
返回consultationsByPerson.getOrDefault(person,0);
}
公共字符串getConsultedOn(){
回访咨询;
}
}
私有静态类数据透视报告{
私有最终映射rowsByConsultedOn=newhashmap();
私有分类集人员=新树集();
专用数据透视表(){}
专用void addData(数据d){
rowsByConsultedOn.computeIfAbsent(d.getConsultedOn(),Row::new).addPerson(d.getConsultedBy());
人员。添加(d.咨询人);
}
公共静态数据透视报告创建(列表){
数据透视报告=新数据透视报告();
list.forEach(report::addData);
返回报告;
}
公共字符串toString(){
String headers=“咨询\t”+String.join(“\t”,persons);
String rows=rowsByConsultedOn.values()
.stream()
.sorted(Comparator.comparing(行::getConsultedOn))
.map(this::rowToString)
.collect(收集器.加入(“\n”));
返回标题+“\n”+行;
}
私有字符串rowToString(行){
返回行。getConsultedOn()+“\t”+
人流()
.map(person->Integer.toString(row.getConsultationsFor(person)))
.collect(收集器.连接(“\t”);
}
}
公共静态void main(字符串[]args){
List List=createListOfData();
数据透视报告=数据透视报告。创建(列表);
系统输出打印(报告);
}
私有静态列表createListOfData(){
列表报告=新建ArrayList();
报告。添加(新数据(“2018年12月4日”、“鲍勃先生”);
报告。添加(新数据(“2018年12月4日”,“Jhon先生”);
报告。添加(新数据(“2018年12月4日”、“鲍勃先生”);
报告。添加(新数据(“2018年12月5日”,“Jhon先生”);
报告。添加(新数据(“2018年12月6日”、“鲍勃先生”);
报告。添加(新数据(“2018年12月6日”,“Jhon先生”);
报告。添加(新数据(“2018年12月7日”、“鲍勃先生”);
报告。添加(新数据(“2018年12月7日”、“史密斯先生”);
返回报告;
}
}

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

下面是一个完整的答案,使用我在评论中解释的技巧,即设计一个类
,表示您希望为每一行生成的内容,即一个
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;
    }
}
公共类Pivo
Map<Pair<String, String>, Integer> map = reports
      .stream()
     .collect(toMap(data -> new Pair<>(data.getConsultedOn(),
                    data.getConsultedBy()), data -> 1, Integer::sum));

Map<String, DataMap> result= new HashMap<>();
class DataMap {
   private String consultedOn;
   private Map<String, Integer> map;
}
Set<String> persons = new HashSet<>();
persons = reports.stream().map(Data::getConsultedBy).collect(Collectors.toSet());
for (Map.Entry<Pair<String, String>, Integer> entry : map.entrySet()) {
      Map<String, Integer> val = new HashMap<>();
      for (String person : persons) {
          if (!person.equals(entry.getKey().getValue()))
              val.put(person, 0);
           else
              val.put(entry.getKey().getValue(), entry.getValue());
       }
        result.put(entry.getKey().getKey(), new DataMap(entry.getKey().getKey(), val));
}
List<DataMap> finalResult = new ArrayList<>(result.values());
public class Application {
    Set<String> doctors = new LinkedHashSet<>();

    private void addDataToReport(Map<String, List<String>> reportMap, String consultedOn, String consultedBy) {
        doctors.add(consultedBy); // set the doctors Set
        reportMap.merge(consultedOn, Arrays.asList(consultedBy)// if key = consultedOn is not there add , a new list
                , (v1, v2) -> Stream.concat(v1.stream(), v2.stream()).collect(Collectors.toList()));//else merge previous and new values , here concatenate two lists
    }

    private void printReport(Map<String, List<String>> reportMap) {
        /*Set Headers*/
        String formatting = "%10s";//give a block of 10 characters for each string to print
        System.out.format(formatting, "consultedOn");
        doctors.forEach(t -> System.out.format(formatting, t));// print data on console without an implicit new line
        System.out.println("\n---------------------------------------");
        /*Set row values*/
        for (Map.Entry<String, List<String>> entry : reportMap.entrySet()) {
            Map<String, Integer> map = new LinkedHashMap<>();
            doctors.forEach(t -> map.put(t, 0)); // initialise each doctor count on a day to 0
            entry.getValue().forEach(t -> map.put(t, map.get(t) + 1));
            System.out.format(formatting, entry.getKey());
            map.values().forEach(t -> System.out.format(formatting, t));
            System.out.println();
        }
    }

    public static void main(String[] args) {
        Application application = new Application();
        Map<String, List<String>> reportMap = new LinkedHashMap<>();
        String MR_JHON = "Mr.Jhon";
        String MR_BOB = "Mr.Bob ";
        application.addDataToReport(reportMap, "04/12/2018", MR_BOB);
        application.addDataToReport(reportMap, "04/12/2018", MR_JHON);
        application.addDataToReport(reportMap, "04/12/2018", MR_BOB);
        application.addDataToReport(reportMap, "05/12/2018", MR_JHON);
        application.addDataToReport(reportMap, "06/12/2018", MR_BOB);
        application.addDataToReport(reportMap, "06/12/2018", MR_JHON);
        application.addDataToReport(reportMap, "07/12/2018", MR_BOB);
        application.printReport(reportMap);
    }
}
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
Map<String, Map<String, Long>> finalMapping = reports.stream()
        .collect(Collectors.groupingBy(DataMap::getConsultedOn,
            Collectors.groupingBy(DataMap::getConsultedBy,Collectors.counting())));
{05/12/2018={Mr.Jhon=1}, 06/12/2018={Mr.Jhon=1, Mr.Bob=1},
07/12/2018={Mr.Bob=1}, 04/12/2018={Mr.Jhon=1, Mr.Bob=2}}
Set<String> consultedBys = reports.stream()
        .map(DataMap::getConsultedBy)
        .collect(Collectors.toSet());
finalMapping.forEach((k, v) -> consultedBys.forEach(c -> v.putIfAbsent(c, 0L)));
{05/12/2018={Mr.Jhon=1, Mr.Bob=0}, 06/12/2018={Mr.Jhon=1, Mr.Bob=1},
07/12/2018={Mr.Jhon=0, Mr.Bob=1}, 04/12/2018={Mr.Jhon=1, Mr.Bob=2}}