0

I have this master and detail object to store header and detail list:

public class MasterDetail {
    private Master master;
    private List<Detail> details;
}

Now I am trying to create a unique list where master - trx date is distinct.

Example input list:

1 | 22/11/2012 | 10.00
2 | 22/11/2012 | 10.00
3 | 23/11/2012 | 11.00
4 | 23/11/2012 | 12.00

The out I needed:

Master1: 22/11/2012
Detail1: 10.00
         10.00

Master2: 23/11/2012
Detail2: 11.00
         12.00

I tried:

List<MasterDetail > masterDetails = new ArrayList<>();
for(Input input: inputList) {
   // this is where to assign the input master and detail into an object
   master = new Master(input.getTransactionDate);
   details = new Detail(input.getAmount);
   MasterDetail assign = new MasterDetail(master, details);
   if (!masterDetails.isEmpty()) {
       for (int i=0; i < masterDetails.size(); i++) {
                if (masterDetails .get(i).getMaster().getTransDate().equals(input.getTransactionDate())) {
                    masterDetails.set(i, assign); // I think the logic problem here
                } else {
                    masterDetails.add(assign );
                }
            };
   } else {
      masterDetails.add(assign)
   }
}

The above code will give many duplicate records.

2
  • 1
    You are not using input for construction of you MasterDetail. master and detail do not change value Commented Oct 1, 2021 at 0:43
  • 1
    this approach is so bad... you can create a Map<Date, List<Details>> and it will be much more efficient since you won't have to iterate on all the master-details on each input you want to add. Commented Oct 1, 2021 at 0:49

2 Answers 2

1

I think a good improvement would be to use a Map<TransDate, MasterDetail> to help you efficiently retrieve the MasterDetail based on the date of the Input in question.

However, I don't know the details of how you're storing dates, and if that'd work easily as the key for a map. If you wanted to stick with a List data structure for whatever reason, here's what I'd do:

List<MasterDetail> masterDetails = new ArrayList<>();
for(Input input: inputList) {
    // find if there's a MasterDetail with the date in question
    MasterDetail target = null;
    for(MasterDetail mDetail : masterDetails){
        if(mDetail.getMaster().getTransDate().equals(input.getTransactionDate()) {
        // we found it
        target = mDetail;
        break;
    }
    if(target == null) {  // never found it, so make a new one
        target = new MasterDetail(input.master, input.detail); // however you create one
        masterDetails.add(target);
    }
    target.details.add(detail);
}

There are still some details I don't know about your code, but at least that logic should make it so there's only one MasterDetail for each date.

Sign up to request clarification or add additional context in comments.

Comments

1

Try this.

record Input(LocalDate transactionDate, double amount) { }
record Master(LocalDate transDate) { }
record Detail(double amount) { }
record MasterDetail(Master master, List<Detail> details) { }

public static void main(String[] args) {
    List<Input> inputList = List.of(
        new Input(LocalDate.of(2012, 11, 22), 10.0),
        new Input(LocalDate.of(2012, 11, 22), 10.0),
        new Input(LocalDate.of(2012, 11, 23), 11.0),
        new Input(LocalDate.of(2012, 11, 23), 12.0));
   
    Map<LocalDate, List<Detail>> map = inputList.stream()
        .collect(Collectors.groupingBy(Input::transactionDate,
            Collectors.mapping(e -> new Detail(e.amount()), Collectors.toList())));

    List<MasterDetail> masterDetails = map.entrySet().stream()
        .map(e -> new MasterDetail(new Master(e.getKey()), e.getValue()))
        .toList();

    for (MasterDetail e : masterDetails)
        System.out.println(e);
}

output:

MasterDetail[master=Master[transDate=2012-11-22], details=[Detail[amount=10.0], Detail[amount=10.0]]]
MasterDetail[master=Master[transDate=2012-11-23], details=[Detail[amount=11.0], Detail[amount=12.0]]]

Or you can also do it by for loops.

    Map<LocalDate, List<Detail>> map = new HashMap<>();
    for (Input input : inputList)
        map.computeIfAbsent(input.transactionDate(),
            k -> new ArrayList<>()).add(new Detail(input.amount()));

    List<MasterDetail> masterDetails = new ArrayList<>();
    for (Entry<LocalDate, List<Detail>> entry : map.entrySet())
        masterDetails.add(new MasterDetail(new Master(entry.getKey()), entry.getValue()));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.