I'm looking for advice on implementing many-to-many. I'm modeling a site such as stack exchange: each Member has many Groups, each Group has many Members. I've introduce a Membership class. This class diagram summarized the code belowEventually there will be question and answer classes, but I want to get this part correct first.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class Member {
private LocalDateTime dateCreated;
private String firstName;
private String lastName;
private String screenName;
private String userID;
private List<Membership> memberships = new ArrayList<Membership>();
public Member(String firstName, String lastName, String screenName, String userID) {
super();
this.dateCreated = LocalDateTime.now();
this.firstName = firstName;
this.lastName = lastName;
this.screenName = screenName;
this.userID = userID;
}
public LocalDateTime getDateCreated() {
return dateCreated;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getScreenName() {
return screenName;
}
public String getUserID() {
return userID;
}
protected void addMembership(Membership m) {
memberships.add(m);
}
public int getNumGroups() {
return memberships.size();
}
public List<Group> getGroups() {
List<Group> groups = new ArrayList<>();
for(Membership membership : memberships) {
groups.add(membership.getGroup());
}
return groups;
}
@Override
public String toString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formatDateTime = dateCreated.format(formatter);
return "Member [dateCreated=" + formatDateTime + ", firstName=" + firstName + ", lastName=" + lastName
+ ", screenName=" + screenName + ", userID=" + userID + "]";
}
public static void main(String[] args) {
Member m = new Member("Les", "Wrigley", "Lesman", "[email protected]");
System.out.println(m);
}
}
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class Group {
private LocalDateTime dateCreated;
private String title;
private String description;
private List<Membership> memberships = new ArrayList<Membership>();
public Group(String title, String description) {
super();
this.title = title;
this.description = description;
this.dateCreated = LocalDateTime.now();
}
public LocalDateTime getDateCreated() {
return dateCreated;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
protected void addMembership(Membership m) {
memberships.add(m);
}
@Override
public String toString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formatDateTime = dateCreated.format(formatter);
return "Group [dateCreated=" + formatDateTime + ", title=" + title + ", description=" + description + "]";
}
public int getNumMembers() {
return memberships.size();
}
public List<Member> getMembers() {
List<Member> members = new ArrayList<Member>();
for(Membership membership : memberships) {
members.add(membership.getMember());
}
return members;
}
public static void main(String[] args) {
Group g = new Group("Java Programming", "Questions related to programming in Java");
System.out.println(g.toString());
}
}
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Membership {
private LocalDateTime dateJoined;
private Member member;
private Group group;
public Membership(Member m, Group g) {
dateJoined = LocalDateTime.now();
this.member = m;
this.group = g;
member.addMembership(this);
group.addMembership(this);
}
public LocalDateTime getDateJoined() {
return dateJoined;
}
public Member getMember() {
return member;
}
public Group getGroup() {
return group;
}
@Override
public String toString() {
String groupName = group.getTitle();
String memberName = member.getLastName() + ", " + member.getFirstName();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formatDateTime = dateJoined.format(formatter);
String msg = String.format("Member:%s, Group:%s, Joined:%s", groupName, memberName, formatDateTime);
return msg;
}
public static void main(String[] args) {
Member m = new Member("Les", "Wrigley", "Lesman", "[email protected]");
Group g = new Group("Java Programming", "Questions related to programming in Java");
Membership membership = new Membership(m,g);
System.out.println(membership.toString());
}
}

Membershipclass as a link betweenMemberandGroup. For this to work, each membership has one and only one member and well as one and only one Group. But a member can have many memberships and a group can have many membership. It was your cardinality that spurred my comment, but looking at yourMembermethods, you already havegetGroupswhich could be a collection ofMemberships. Hope this makes some sense. \$\endgroup\$