-2

I am trying to achieve the grouping & summing of values in an array. In the data shown below the values under column Surcharge need to be summed for date - note combination & stored in another list.

I referred to Link1 Link2 & Link3 but unable to figure what mistake I am doing. Hope the issue faced by me is clear, await guidance.

Data (read from excel):

  • Date | Note No. | Surcharge
  • 29-Jan-2016 | 1234 | 12.2
  • 29-Jan-2016 | 1234 | 10.5
  • 28-Jan-2016 | 2468 | 9.25
  • 28-Jan-2016 | 2468 | 14.4
  • 28-Jan-2016 | 2468 | 13.3
  • 27-Jan-2016 | 1357 | 17.2
  • 27-Jan-2016 | 1357 | 18.7

Code Data Model:

public class ModelSurcharge {
private LocalDate cNoteDate;
private int cNote;
private double surcharge;

public ModelBrokerage(LocalDate cNoteDate, int cNote, double surcharge) {
    this.cNoteDate = cNoteDate;
    this.cNote = cNote;
    this.surcharge= surcharge;
}

public LocalDate getcNoteDate() {
    return cNoteDate;
}

public int getcNote() {
    return cNote;
}

public double getSurcharge() {
    return surcharge;
}
}

Code Main class:

File fileCNote = null;
try {
     fileCNote = new File("c:/surcharge.xlsx");
} catch (IOException e) {
     e.printStackTrace();
}
// Read data from excel file
List<List<XSSFCell>> dataSurcharge = iFaceXLSX.readData(fileCNote);
// Skip header line & filter out rows which do not have surcharge amount
dataSurcharge = dataSurcharge .stream().skip(1).filter(p -> p.get(6).getNumericCellValue() > 0).collect(Collectors.toList());

// Transfer data read from excel to the data model
List<ModelSurcharge> surcharges= new ArrayList<>();
dataSurcharge.forEach(e -> {
     List<ModelSurcharge> temp = Arrays.asList(new ModelSurcharge(
                e.get(0).getDateCellValue().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
                (int) e.get(1).getNumericCellValue(),
                (e.get(3).getNumericCellValue() + e.get(4).getNumericCellValue()) * e.get(6).getNumericCellValue()));
        surcharges.addAll(temp);
    });

//Output to console
    surcharges.stream().collect(groupingBy(Function.identity(),
            ()->new TreeMap<>(
                    Comparator.<ModelSurcharge,LocalDate>comparing(p->p.getcNoteDate()).thenComparing(p->p.getcNote())),
            Collectors.summingDouble(foo->foo.getSurcharge())))
            .forEach((group,surcharge) ->
                    System.out.println(group.getcNoteDate()+"\t"+group.getcNote()+"\t"+surcharge));

// Collecting to another list does not work
List<ModelSurcharge> output = surcharges.stream()
            .collect(groupingBy(p -> p.getcNoteDate(), Collectors.summingDouble(p -> p.getSurcharge())));

error:

Cannot resolve method 'getcNoteDate()'
Cannot resolve method 'getSurcharge()'
Community
  • 1
  • 1
iCoder
  • 1,406
  • 6
  • 16
  • 35
  • Could you please simplify and clarify your question by removing all the links and irrelevant pieces of code, and only provide the relevant code: the ModelSurcharge class, a complete but minimal example showing the code that does not compile, and the exact and complete compiler error messages? – JB Nizet Jun 19 '16 at 08:41
  • @JBNizet I have made the changes as informed by you. I hope I have provided the necessary info & the issue I face is more clear. Apologies to you & the forum – iCoder Jun 19 '16 at 09:39

1 Answers1

2

Your ModelSurcharge class doesn't compile,because it has a constructor with the name ModelBrokerage. The beginning of your main code doesn't compile either: the File constructor never throws any IOException.

But the whole compilation problem can be reduced to the following code, which is much more concise and doesn't have any dependency of external libraries:

public class ModelSurcharge {
    private LocalDate cNoteDate;
    private int cNote;
    private double surcharge;

    public ModelSurcharge(LocalDate cNoteDate, int cNote, double surcharge) {
        this.cNoteDate = cNoteDate;
        this.cNote = cNote;
        this.surcharge = surcharge;
    }

    public LocalDate getcNoteDate() {
        return cNoteDate;
    }

    public int getcNote() {
        return cNote;
    }

    public double getSurcharge() {
        return surcharge;
    }

    public static void main(String[] args) {
        List<ModelSurcharge> surcharges= new ArrayList<>();
        List<ModelSurcharge> output = surcharges.stream()
                                                .collect(groupingBy(p -> p.getcNoteDate(), 
                                                                    Collectors.summingDouble(p -> p.getSurcharge())));
    }
}

The error message is misleading. But it's caused by the fact that the compiler tries inferring the type of p from the context, but it can't because you're trying to assign the right-hand-side expression to a List<ModelSurcharge>, although groupingBy produces a Map, not a List. Use the right type for the output variable (Map<LocalDate, Double>), and the error will disappear.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks. I missed the usage of Map. But with Map i will not be able to get the Note No. How should i use the Map function to get the data of all 3 columns. I guess I should group by LocalDate & Integer, not sure how to achieve that. – iCoder Jun 19 '16 at 10:22
  • Write another question, reducing the code to a minimum as I did, and explain what you really want to get as output. – JB Nizet Jun 19 '16 at 10:24
  • OK figured it out. I used Map. Thanks once again for your help. – iCoder Jun 19 '16 at 10:26