Reddy Reddy - 1 month ago 5
Java Question

Duplicate items are not added to the list

I'm trying below java code and would want to add all the matching items to a list based on the input list. Below I've the input list, look up list and the return matching list. Currenlty, the below code fails when we have duplicate values in the input list. Can someone advice how I can resolve this ? Thanks in advance.

import java.time.YearMonth;
import java.util.*;
import static java.util.stream.Collectors.toList;


public class PeriodTest {

public static void main(String[] args) {

//Input
List<YearMonth> yearMonths = Arrays.asList(YearMonth.of(2016, 9), YearMonth.of(2016, 9));

//Look up
List<PeriodCode> periodCodes = Arrays.asList(new PeriodCode(2016, 9), new PeriodCode(2017, 9));

//Code
List<PeriodCode> actualOutput = periodCodes.stream().filter(item -> yearMonths.contains(YearMonth.of(item.getYear(), item.getMonth()))).collect(toList());
List<PeriodCode> expectedOutput = Arrays.asList
(
new PeriodCode(2016, 9),
new PeriodCode(2016, 9)
);

System.out.print(actualOutput.size() == expectedOutput.size());//false 1 vs 2

}

private static class PeriodCode {

private int year;
private int month;

PeriodCode(int year, int month) {
this.year = year;
this.month = month;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PeriodCode)) return false;

PeriodCode that = (PeriodCode) o;

if (year != that.year) return false;
return month == that.month;

}

@Override
public int hashCode() {
int result = year;
result = 31 * result + month;
return result;
}

int getYear() {
return year;
}

void setYear(int year) {
this.year = year;
}

int getMonth() {
return month;
}

void setMonth(int month) {
this.month = month;
}
}

}

Answer

It's not clear why you expect duplicates to be gone, since you haven't actually done anything to remove them.

Adding .distinct() to the stream chain might help, though.

UPDATE: write

periodCodes.stream()
    .flatMap(periodCode -> 
        yearMonths.stream()
            .filter(YearMonth.of(periodCode.getYear(), periodCode.getMonth())::equals)
            .map(ym -> periodCode))
    .collect(toList())
Comments