If a woman has a partner, erase that partner's partner.
I need to retrieve her partner then make that partner single.
How do I combine getPartner() with erasePartner()
if (w.hasPartner() == true) {
w.getPartner().erasePartner();
}
import java.util.*;
public class Person {
public static final int NOBODY = -1;
private String name;
private List<Integer> preferences;
private List<Integer> oldPreferences;
private int partner;
public Person(String name) {
this.name = name;
preferences = new ArrayList<Integer>();
oldPreferences = new ArrayList<Integer>();
erasePartner();
}
public void erasePartner() {
partner = NOBODY;
}
public boolean hasPartner() {
return partner != NOBODY;
}
public int getPartner() {
return partner;
}
public void setPartner(int partner) {
this.partner = partner;
}
public String getName() {
return name;
}
public boolean hasChoices() {
return !preferences.isEmpty();
}
public int getFirstChoice() {
return preferences.get(0);
}
public void addChoice(int person) {
preferences.add(person);
oldPreferences.add(person);
}
public List<Integer> getChoices() {
return preferences;
}
public int getPartnerRank() {
return oldPreferences.indexOf(partner) + 1;
}
}
Right now you have partner as an int. You cannot call methods on an int since it is a primitive type. However this doesn't make much sense in your context since you are erasing w's partner and not the partner's partner. Instead just call:
if (w.hasPartner() == true) {
w.erasePartner();
}
Also your code doesn't make much sense. Why is the partner an int? Why wouldn't it be a Person object. You could change your code to:
private Person partner;
And
public Person getPartner() {
return partner;
}
So that partner points to another Person object instead of an int
You need to be able to get the Persona that the partner field corresponds to if you want to erase the partner's partner.
Given the code that you have, every Person should have a corresponding id that is an int, which is the value the partner field stores. You'll need some way to store these mappings such as a Map<Integer, Persona> that lives outside the Person class, and whenever you create a Person you have to put it in the map along with its id (which you can generate however you like as long as it's unique).
With this map you can then access the Person that corresponds to the partner int and erase its partner
if (w.hasParter()) {
Person partner = personMap.get(w.getPartner());
partner.erasePartner()
}
assuming the partner exists in the map (which you may want to check for).
Okay I kinda figured it out. I did it another way. Goes through each person and test's to see if person p is partner with firstChoice then deletes the p's partner. Kinda long way it seems but it works :)
for (Person p : list1) {
if (p.getPartner() == firstChoice) {
p.erasePartner();
}
Related
public class LocationBasedRole extends AbstractEntity{
#ManyToMany(fetch=FetchType.LAZY)
private Set<Role> roles=new HashSet<Role>();
#ManyToMany(fetch=FetchType.LAZY)
private Set<Location> locations=new HashSet<Location>();
}
public class Role extends AbstractEntity{
private String name;
}
public class Location extends AbstractEntity{
private String location;
}
I have an entity named locationBasedRole which has 2 properties named roles and locations. Both roles and locations have a #ManyToMany relation with locationBasedRole.
Now I want to have one property of each in a Vaadin Table. It should be something like this,
public class UserForm extends OgsAbstractForm<User>{
MTable<LocationBasedRole> locationBasedRoleTable = new MTable<LocationBasedRole>().withHeight("100%").withWidth("100%");
#Override
protected Component createContent() {
Set<LocationBasedRole> lbRoles=new HashSet<LocationBasedRole>();
roles.addAll(locationBasedRoleFasade.findAll());
BeanItemContainer<LocationBasedRole> bean=new BeanItemContainer<LocationBasedRole>(LocationBasedRole.class);
//It returns an error on the next both lines and I know the reason, but don't know how to solve it.
// If it was no ManyToMany relation and the properties weren't a collection, it would work
bean.addNestedContainerProperty("roles.name");
bean.addNestedContainerProperty("locations.location");
bean.removeContainerProperty("persistent");
bean.removeContainerProperty("id");
bean.addAll(lbRoles);
locationBasedRoleTable.setContainerDataSource(bean);
return new VerticalLayout(locationBasedRoleTable);
}
}
When I remove the properties from the NestedContainerProperties it shows me at least something in the table.
bean.addNestedContainerProperty("roles");
bean.addNestedContainerProperty("locations");
I could use any help!
Thanks in advance!
So if I understand your question right, you want to have the Collections of your BeanItemContainer-Entity displayed in one column each?
I see two possibilities for that.
Option 1 - use a wrapper class for your Sets and use addNestedContainerBean
One possibility would be to not use Sets inside your LocationBasedRole but to use a wrapper class that extends HashSet.
Then you could use the addNestedContainerBean method.
I created a small example with the BeanItemContainer-Entity Team
public class Team {
private String teamName;
private Members teamMembers;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Members getTeamMembers() {
return teamMembers;
}
public void setTeamMembers(Members teamMembers) {
this.teamMembers = teamMembers;
}
}
Which consists of a name and teamMembers. The latter is of type Members:
public class Members extends HashSet<TeamMember> {
public String getMembers() {
return this.stream()
.map(member -> member.getFirstName() + " " + member.getLastName())
.collect(Collectors.joining(","));
}
}
Which is a simple wrapper for the Set that contains instances of TeamMember:
public class TeamMember {
private String firstName;
private String lastName;
private Integer age;
// getters and setters
}
As you can see in the Members class, there is a method getMembers which returns a String, containing a comma separated list of the team members names.
If we now use addNestedContainerBean("teamMembers") Vaadin tries to display all properties contained in the class Members. Vaadin will think getMembers is a getter for a String property called members and so generate a column for it.
Vaadin will also display a column "empty" because it will find the isEmpty method of Set and think empty is a property to display in a column. So we tell Vaadin to remove that column.
The final code of my example looks like:
protected Component createContent() {
Set<Team> teams=new HashSet<>();
for (int teamCounter = 0; teamCounter < 5; teamCounter++) {
Team team = createTeam();
addMembersToTeam(5, team);
teams.add(team);
}
BeanItemContainer<Team> bean=new BeanItemContainer<>(Team.class);
bean.addNestedContainerBean("teamMembers");
bean.removeContainerProperty("teamMembers.empty");
bean.addAll(teams);
teamTable.setContainerDataSource(bean);
return new VerticalLayout(teamTable);
}
The result looks like:
Option 2 - create fake getters and use addNestedContainerProperty
The only thing you have to do for this is extend your BeanItemContainer-Entity (LocationBasedRole) and create a fake getter for each Set you want to be displayed in a column. In your example those two fake getters could be public String getTheRoles() and public String getTheLocations(). Then you can use bean.addNestedContainerProperty("theRoles") and bean.addNestedContainerProperty("theLocations").
In my example my TeamMember class (the counterpart to your Role / Location classes) would still look like in the option above:
public class TeamMember {
private String firstName;
private String lastName;
private Integer age;
// getters and setters
}
And my Team class (your LocationBasedRole) would look like:
public class Team {
private String teamName;
private Set<TeamMember> teamMembers;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Set<TeamMember> getTeamMembers() {
return teamMembers;
}
public void setTeamMembers(Set<TeamMember> teamMembers) {
this.teamMembers = teamMembers;
}
public String getMembers() {
if (teamMembers != null) {
return teamMembers.stream()
.map(member -> member.getFirstName() + " " + member.getLastName())
.collect(Collectors.joining(","));
} else {
return "No members";
}
}
}
Now you can tell vaadin to add the (not existing) property "members" and Vaadin will find the getter getMembers and use this for generating the column. We also have to tell vaadin not to display the original "teamMembers" property. So the final code is:
protected Component createContent() {
Set<Team> teams=new HashSet<>();
for (int teamCounter = 0; teamCounter < 5; teamCounter++) {
Team team = createTeam();
addMembersToTeam(5, team);
teams.add(team);
}
BeanItemContainer<Team> bean=new BeanItemContainer<>(Team.class);
bean.addNestedContainerProperty("members");
bean.removeContainerProperty("teamMembers");
bean.addAll(teams);
teamTable.setContainerDataSource(bean);
return new VerticalLayout(teamTable);
}
and the result looks like:
no idea if this is possible, cant seem to find an answer online so here it goes.
I'm modeling an ad bidding platform in java, where advertisers submit offers to show ads on a site and the highest bid wins.
I created a Bid object(Which contains the price offered, ad url, and name of the bidder for tracking) and an Auction object that's really just a TreeMap of prices(as ints) and Bids (as Bid objects).
I know this is a super rudimentary look at such a thing, but is it possible to have the Bid object constructor add the Bid to the Auction? Just to stick to DRY principles? If not possible from the constructor, is there somewhere else I can automate this outside of the Main method?
Bid.class
public class Bid {
private int cents;
private String location;
private String bidServer;
public Bid(int cents, String location, String bidServer) {
this.cents = cents;
this.location = location;
this.bidServer = bidServer;
}
public int getCents() {
return cents;
}
public String getLocation() {
return location;
}
public String getBidServer() {
return bidServer;
}
}
Auction.class
import java.util.Map;
import java.util.TreeMap;
public class Auction {
private Map<Integer, Bid> bids ;
public Auction() {
this.bids = new TreeMap<>();
}
public void addBid (Bid bid){
bids.put(bid.getCents(), bid);
}
public Bid getHighestBid(){
return bids.get(((TreeMap<Integer, Bid>) bids).lastKey());
}
public void clearBids(){
bids.clear();
}
}
Change the method addBid in Auction:
public void addBid(int cents, String location, String bidServer) {
Bid bid = new Bid(cents, location, bidServer);
bids.put(cents, bid);
}
You could put Auction and Bid in the same package and make the constructor of Bid package-private.
Also, you should declare bids like this:
private SortedMap<Integer, Bid> bids;
In that case you can write method getHighestBid like this:
public Bid getHighestBid() {
return bids.get(bids.lastKey());
}
You could pass the Auction object when you construct the bid and then just add the Bid as this like so:
public Bid(int cents, String location, String bidServer, Auction auction) {
this.cents = cents;
this.location = location;
this.bidServer = bidServer;
auction.addBid(this);
}
public abstract class Employee {
String name;
String position
public Employee(String name, String position) {
this.name = name;
this.position = position
}
}
public class Pilot extends Employee {
public Pilot(String name,String position) {
super();
}
public void flight() {//flight the plane}
//getter and setter for the fields
}
public class Attendance extends Employee {
public Attendance(String name,String position) {
super();
}
public Food servingFood(String foodName) {}
}
// there will be many other positions
public class Company {
HashMap<String, ArrayList<Employee>> employeeTable; //values is a list of workers, key is the position
public Company() {this.employeeTable = new HashMap<>();}
public initializeEmployeeTable(file) {} //read file, and create keys in map (file contains information of the position)
public Worker hireEmployee(String position, String name){
if (position.equals("pilot")) {
Pilot p = Pilot(name);
employeeTable.get("pilot").add(p);
return p
}
else if (position.equals("flightAttendance")) {// the else if statement continuous to check the other position; }
}
public Worker callEmployee(String position, String name) {
for ( Employee e : employeeTable.get(position) ) {
if e.getName().equals(name) {
return e;
}
}
return null;
}
public static void main(String[] args) {
Company company = new Company();
company.initializeEmployeeTable(filePath);
File eventFile = new File(filePath); // event file describes what's happening in real world; read the lines, and call the program so that program simulates the real world events
sc = new Scanner(eventFile);
do {
String currentEvent = sc.nextLine();
String[] currentEventParts = currentEvent.split(", ");
if (currentEvent[0].equals("New Airplane")) { // currentEvent looks like {"New Airplane", "Attendance"// this part can be other position name, "Linda"}
Worker w = company.hireEmployee(currentEventParts[1], currentEventParts[2]); }
else if ((currentEvent[0].equals("flying"))) {
Worker w = company.callEmployee(currentEvent[0], currentEvent[1])
if (w.getPosition().equals("Pilot")) {(Worker) w.flight()}
if (w.getPosition().equals("Attendance")) {(Worker) w.serveFood()}
}
}
The reason there is HashMap for employee because there will be many positions; and reading the event file (when the first index is "New Airplane"); I don't want to go check the following index (would be name and position) with so many if statements to create corresponding employee. But when comes to calling specific methods, I need type casting now; since each method can be different (different type parameter, return type); so it's not ideal to have this methods be abstract method in super class employee and have the subclass implements the body.
Any advices: employee data structure; reading file strategy, pattern design would be appreciated. thanks
I'm making a contacts app, this is my model.
public class Contact {
private RelationShip relationShip;
public static class RelationShip {
private Friend friend;
private Enemie enemie;
private Family family;
private class Family {
private Brother brother;
private Sister sister;
}
}
}
I want to create it you can do it the way suiguiente.
RelationShip realation = new RelationShip(RelationShip.Friend);
Contact contact = new Contact(realation);
I want to establish the kind of relationship in a variable. Really do not know how to ask the question. an example would be something like this:
layout.setOrientation (LinearLayout.VERTICAL);
LinearLayout.VERTICAL is a constant or an enumerate. Take a look here for example.
To achieve the same behavior in your code set those values as constants (usually int).
public static class RelationShip {
public static final int FRIEND = 0;
public static final int ENEMIE = 1;
public static final int FAMILY = 2;
...
}
public class Contact {
private int relationshipType;
...
public void setRelationShipType(int relationShip) {
}
public boolean areWeFriends() {
if (relationshipType==Relationship.FRIEND)
return true;
else
return false;
}
...
}
You can then set the relationship setRelationShipType(Relationship.FRIEND). Or check if the relationship of Contact HerryPotter is a friend with HarryPotter.areWeFriends()
EDIT:
Actually the correct way is indeed the one suggested by alfasin: using enumerates.
public enum RelationShip {
FRIEND, ENEMIE, FAMILY
}
public class Contact {
private RelationShip relationshipType;
public void setRelationShipType(RelationShip relationShip) {
...
}
public boolean areWeFriends() {
if (relationshipType==Relationship.FRIEND)
return true;
else
return false;
}
}
After I read online E-book.They said the benefit of encapsulation is "A class can change the data type of a field and users of the class do not need to change any of their code.". I don't understand what they say in the point. What is the main meaning of the point? Can you give an example,please?
Let's take a simple class Vehicles, which maintains a list:
public class Vehicles {
private ArrayList<String> vehicleNames;
Vehicles() {
vehicleNames = new ArrayList<String>();
}
public void add(String vehicleName) {
vehicleNames.add(vehicleName);
}
}
This will be used by a client in the following way:
public class Client {
Public static void main(String []args) {
Vehicles vehicles = new Vehicles();
vehicles.add("Toyota");
vehicles.add("Mazda");
}
}
Now if Vehicles changes its internal private vehicleNames field to be a LinkedList instead, Client would be unaffected. That is what the book is talking about, that the user/client does not need to make any changes to account for the changes in the class due to encapsulation.
Encapsulation is really important in Object-Oriented Programming. Using encapsulation, you can hide information from users who use your class library/API.
"And why do I need to hide stuff from the users?", you ask. There are a lot of reason. One main reason is that some users who are naughty or just don't know what the API is doing may mess with your classes and stuff. Let me give you an example.
Suppose you have a class here:
public class Computer {
public int coreCount;
}
As you can see here, coreCount is declared public. That means all other classes can access it. Now imagine a naughty person do this:
Computer myPC = new Computer ();
myPC.coreCount = 0;
Even fools can tell that this doesn't make any sense. It might also affect your program's other stuff. Imagine you want to divide by the core count. An Exception would occur. So to prevent this, we should create setters and getters and mark the field private.
C# Version:
public class Computer {
private int coreCount;
public int CoreCount {
get {return coreCount;}
set {
if (value > 0)
coreCount = value;
}
}
}
Java version
public class Computer {
private int coreCount;
public int getCoreCount () {return coreCount;}
public void setCoreCount (int value) {
if (value > 0)
coreCount = value;
}
Now no one can set the core count to non-positive values!
Here's an example of encapsulation. Say we have a Person class, like so
class Person {
private String name;
private String email;
public String getName() { return this.name; }
public String getEmail() { return this.email; }
public void setName(String name) { this.name = name; }
public void setEmail(String email) { this.email = email; }
}
And at some point, we decide we need to store these values not as a couple strings, but as a HashMap (for some reason or another).
We can change our internal representation without modifying the public interface of our Person class like so
class Person {
HashMap<String, String> data;
public Person() {
this.data= new HashMap<String, String>();
}
public String getName() { return this.data.get("name"); }
public String getEmail() { return this.data.get("email"); }
public void setName(String name) { this.data.put("name", name); }
public void setEmail(String email) { this.data.put("email", email); }
}
And from the client code perspective, we can still get and set Strings name and email without worrying about anything else.