Не лучшим образом, выглядит не очень аккуратно, но поскольку других ответов нет, я выложу то, что пришло мне в голову:
Резюме
public class ParentListing {
//all fields here except 'id'
//constructors, getters, setters, toString, equals, hashcode
}
public class Listing extends ParentListing {
private int id;
public ParentListing getParent() {
//not too happy creating a new object here, perhaps there is a better way
return new ParentListing(getField1(), getField2());
}
//constructors, getters, setters, toString, equals, hashcode
}
и используйте его следующим образом:
public static void main(String[] args) {
List<Listing> list = List.of(
new Listing(1, "f1", "f2"),
new Listing(2, "f10", "f20"),
new Listing(3, "f1", "f2"));
//Following map maps listings (without id) to the list of IDs.
//You can probably stop here and use it as it is. Or else see the next map.
Map<ParentListing, Set<Integer>> collect = list.stream()
.collect(Collectors.groupingBy(
Listing::getParent,
Collectors.mapping(Listing::getId, Collectors.toSet())));
Map<Listing, Integer> map = collect.entrySet().stream()
.map(e -> Map.entry(
new Listing(e.getValue().stream().findFirst().get(), e.getKey()),
e.getValue().size()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(map);
}
Выход
{Listing {id = 2, field1 = f10, field2 = f20} = 1, Листинг {id = 1, field1 = f1, field2 = f2} = 2}
Полный код
@Getter
@Setter
public class ParentListing {
private String field1;
private String field2;
public ParentListing(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParentListing that = (ParentListing) o;
return Objects.equal(field1, that.field1) &&
Objects.equal(field2, that.field2);
}
@Override
public int hashCode() {
return Objects.hashCode(field1, field2);
}
@Override
public String toString() {
return "ParentListing{" +
"field1='" + field1 + '\'' +
", field2='" + field2 + '\'' +
'}';
}
}
@Getter
@Setter
public class Listing extends ParentListing {
private int id;
public Listing(int id, String field1, String field2) {
super(field1, field2);
this.id = id;
}
public Listing(int id, ParentListing parentListing) {
this(id, parentListing.getField1(), parentListing.getField2());
}
public ParentListing getParent() {
return new ParentListing(getField1(), getField2());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Listing listing = (Listing) o;
return id == listing.id;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), id);
}
@Override
public String toString() {
return "Listing{" +
"id=" + id +
", field1=" + getField1() +
", field2=" + getField2() +
"} ";
}
}