So I am a student who just started with java and got this task.
''Make a class which represent an episode in a TVSeries. This should contain instance variables for episode, season, title and playtime. We would also make to constuctors to be able to create an episode, one with all the instance variables, and one without playtime (overloading).
Then make a class which represent a TVSeries. This should contain instance variables for title, description, release date and a list with episodes.
An episode shall be able to individually added via a methode addEpisodes(Episode theEpisode)''
So I have made the two classes (Episode with two constructors and TVSeries), but don't know what the addEpisodes(Episode theEpisode) methode shall contain. Would appreciate some help :)
public class TVSerie {
private String titel;
private String description;
private LocalDate releaseDate;
private ArrayList<Episode> listeWithEpisods;
public void addEpisode(Episode theEpisode) {
ArrayList<Episode> listeWithEpisods = new ArrayList<>();
listeWithEpisods.add(theEpisode);
System.out.println(listeWithEpisods);
}
public class Episode extends TVSerie {
private int episodeNumber;
private int sesongNumber;
private String titel;
private int playtime;
public Episode(int episodeNumber, int sesongNumber, String titel, int playtime) {
this.episodeNumber = episodeNumber;
this.sesongNumber = sesongNumber;
this.titel = titel;
this.playtime = spilletid;
}
public Episode(int episodeNummer, int sesongNummer, String tittel) {
this.episodeNumber = episodeNumber;
this.sesongNumber = sesongNumber;
this.titel = titel;
}
As the assignment suggest, TVSeries should have List and addEpisode needs to add it to your list.
public class TVSerie {
private String titel;
private String description;
private LocalDate releaseDate;
private List<Episode> listeWithEpisods;
public TVSerie(){
listeWithEpisods = new ArrayList<>();
}
public void addEpisode(Episode theEpisode) {
listeWithEpisods.add(theEpisode);
System.out.println(listeWithEpisods);
}
You need to initialize your list only once, inside the constructor.
In your implementation every time addEpisode is used you create new instance of your episode list and therefore deletes the former one.
In addition, Episode should not extends TVSerie, it is not a type of it. It is a type of it's own not related to TVSerie.
Related
I am working in Java and I want to make a deep copy of a MoleculeDTO object. I tried to make a copy constructor too, but it is not working and it is refering to the initial object.
public class MoleculeDTO {
private int ID;
private String name;
private List<AtomDTO> atoms = new ArrayList<>();
private int nrAtoms =0;
public MoleculeDTO(String name, List<AtomDTO> atoms, int nrAtoms) {
this.name = name;
this.atoms = atoms;
this.nrAtoms = nrAtoms;
}
public MoleculeDTO(MoleculeDTO molecule) {
this(molecule.getName(), molecule.getAtoms(), molecule.getNrAtoms());
}
...getter, setter
}
Here is class AtomDTO.
public class AtomDTO{
private int ID;
private String name;
private String symbol;
private int nrOfBonds;
private List<BondDTO> bonds = new ArrayList<>();
private int type;
private AnchorNode anchorNode;
public AtomDTO(String name, String symbol, int nrOfBonds, List<BondDTO> bonds, int type) {
this.name = name;
this.nrOfBonds = nrOfBonds;
this.bonds = bonds;
this.type = type;
}
public AtomDTO(AtomDTO copyAtom) {
this(copyAtom.getName(),copyAtom.getSymbol(), copyAtom.getNrOfBonds(), copyAtom.getBonds(), copyAtom.getType());
}
...getter, setter
}
Here is class BondDTO.
public class BondDTO {
private int ID;
private int otherAtomID;
private int otherAtomType;
private int bondType;
public BondDTO(int otherAtomID, int otherAtomType, int bondType) {
this.otherAtomID = otherAtomID;
this.otherAtomType = otherAtomType;
this.bondType = bondType;
}
public BondDTO(BondDTO copyBond) {
this(copyBond.getOtherAtomID(), copyBond.otherAtomType, copyBond.bondType);
}
...getter, setter
}
Your copy constructors are just doing shallow copies of each field. That's fine for strings because they're immutable, and it's fine for ints because they're primitive (which means they lack identity and are immutable). In those cases, there is no important difference between shallow and deep copies. But it doesn't work in general for lists because lists can be mutable and so can their elements. So instead of just pointing at the same list, you need to make a new list and deep copy each element of the original list into the new one.
Use this helper method to make deep copies of any lists:
static <T> List<T> deepCopyList(List<T> list, UnaryOperator<T> deepCopyElement) {
return list.stream().map(deepCopyElement).collect(
Collectors.toCollection(ArrayList::new)
);
}
Like so:
public AtomDTO(AtomDTO that) {
this(that.getName(), that.getType(), deepCopyList(that.getBonds(), BondDTO::new));
}
I'm trying to make a program that matches a clients interests with aspects of a holiday, I have an array list of holidays and an array list of strings for the clients interests and I wanted to create a new array list which would add all elements that are contained in both. This is what I have but it comes up with a null pointer exception, Any ideas where I've gone wrong?
the debugger points towards the disjoint and at " int c1size = c1.size();"
Relevant parts of code...
In main...
ClientExt1 marina = new ClientExt1("Marina",14321,"marina.calder1#btinternet.com");
ArrayList<String> interests = new ArrayList<>();
interests.add("History");
interests.add("Music");
marina.setInterests(interests);
holidaySeller.getHolidayMatches(marina);
Client...
public class ClientExt1 {
private String name;
private int id;
private String email;
private HolidayExt1 holidayBooked;
private ArrayList<String> interests;
public ClientExt1(String name, int id, String email){
this.name=name;
this.id=id;
this.email=email;
}
public void setInterests(ArrayList interests) {
this.interests=interests;
}
public ArrayList<String> getInterests(){
return interests;
Company class...
public class CompanyExt1 {
protected ArrayList<StaffExt1> staffMembers;
protected ArrayList<HolidayExt1> holidays;
protected ArrayList<GuideExt1> holidayGuides;
protected ArrayList<AdventureExt1> adventureHolidays;
protected ArrayList<CultureExt1> cultureHolidays;
private ArrayList<String> matchedHolidays;
public ArrayList<String> findHolidayMatch(ClientExt1 client) {
ArrayList interests = client.getInterests();
int i;
for (i = 0; i < holidays.size() && i< interests.size(); i++) {
if (!Collections.disjoint(holidays.get(i).getAspects(), interests)) {
matchedHolidays.add(holidays.get(i).getName());
}
}
return matchedHolidays;
}
public void getHolidayMatches(ClientExt1 client){
System.out.println(client.getName() + ", the holidays recommended to you based on your interests from this company are:" + findHolidayMatch(client));
}
}
You need to initialize holidays before you use it and matchedHolidays before you add values to it in findHolidayMatch
I would actually make matchedHolidays a local variable instead of a class member since it is only used in the scope of the findHolidayMatch method.
I have an input like this
private String[] one = {"North America","USA","IL","ch","chicago"};
private String[] two = {"North America","USA","WI","ma","madision"};
private String[] three = {"Asia","India","AP","nlr","nlr"};
private String[] four = {"asia","india","TN","ch","chennai"};
and will add to List like this.
private List<String[]> entities = new ArrayList<>();
private void initializeStringArray(){
entities.add(one);
entities.add(two);
entities.add(three);
entities.add(four);
}
I want now this entities to be converted to nested objects like
Continent->Country->State->District->City. Would like to what will be the best possible solution to create nested objects. It is very confusing while creating nested objects. Can anyone give me best solution.
public class Continents{
private String name;
private Collection<Country> countryCollection;
}
public class Country{
private String name;
private Collection<State> stateCollection;
}
public class State{
private String name;
private Collection<District> districtCollection;
}
public class District{
private String name;
private Collection<City> cityCollection;
}
public class City{
private String name;
}
CAVEAT: I do not know how to determine which solution might be the 'best possible solution'. Here, though, is one possible solution, maybe not the best....
I assume that you wish to have only one instance of 'North America' which is used for both 'chicago' and 'madision' . So maybe create a class 'World' that has a dictionary of continents:
Untested code:
public final class World {
public static final World shared = new World(); // singleton
private Map<String, Continent> continents = new HashMap<>();
private World() {} // enforce singleton
public final Continent getContinent(String name) {
String lowerCaseName = name.toLowerCase();
Continent continent = this.continents.get(lowerCaseName);
if (null == continent) {
continent = new Continent(name);
this.continents.put(lowerCaseName, continent);
}
return continent;
}
}
World acts as a collection of unique Continent instances, and as a factory for new Continents.
Continent would then have a map of Country, and act as a factory for country, with pattern repeating down your hierarchy.
Then your code becomes similar to (untested code):
Continent continent = World.getContinent(one[0]);
Country country = continent.getCountry(one[1]);
State state = country.getState(one[2]);
.........
The key point here is that each level acts as a container and a factory for unique instances of the next level down.
Im making a Coin class with a static arraylist that stores every instance of the class created, howevered I need to initiate that list with an initial instance, and I have not figured out how to do it without adding it twice (because of a redundant code), any suggestions?
public class Coin {
private static ArrayList<String> coinNames = new ArrayList<>();
private static ArrayList<String> coinAbbreviations = new ArrayList<>(Arrays.asList("CLP"));
private static ArrayList<Coin> coins =
new ArrayList<>(Arrays.asList(new Coin("Pesos chilenos", "CLP", 1f, "CLP")));
private static HashMap<String,Float> exchangeRates;
private String coinName;
private String coinAbbreviation;
private Float coinValue;
private String unit;
public Coin(String coinName, String coinAbbreviation, Float coinValue, String unit) {
assert !coinAbbreviations.contains(coinAbbreviation) : "Coin abbreviation already used";
assert coinAbbreviations.contains(unit) : "Coin unit non existent.";
assert !coinNames.contains(coinName) : "Coin name already used.";
this.coinName = coinName;
this.coinAbbreviation = coinAbbreviation;
this.coinValue = coinValue;
this.unit = unit;
coins.add(this);
}
}
If you insist on having mutable static variables at all -- it's generally not a good idea to do things like this at all -- you could do
private static ArrayList<Coin> coins =
new ArrayList<>();
static {
new Coin("Pesos chilenos", "CLP", 1f, "CLP");
}
...which adds the element to the list immediately.
What stops you initialising your list in its declaration and then just adding each instance to the list in the constructor?
You could alternatively design your application using some best-practice patterns. You want to keep a registry of all created coins. This is best kept outside of the Coin class itself. You could have a class that manages the creation of coins and keeps a list of those that it created. The Coin class itself can be an interface, if you like, as that way you ensure that it cannot be created other than by the CoinFactory.
public interface Coin {
String name();
String abbreviation();
BigDecimal value();
String unit();
}
And the Coin factory class:
public class CoinFactory {
// Concrete coin is an internal implementation class whose details don't
// need to be known outside of the CoinFactory class.
// Users just see it as interface Coin.
private static class ConcreteCoin implements Coin {
private final String name;
private final String abbreviation;
private final BigDecimal value;
private final String unit;
ConcreteCoin(String name, String abbreviation, BigDecimal value, String unit) {
this.abbreviation = abbreviation;
this.name = name;
this.value = value;
this.unit = unit;
}
public String name() { return name; }
public String abbreviation() { return abbreviation; }
public BigDecimal value() { return value; }
public String unit() { return unit; }
}
// Sets for enforcing uniqueness of names and abbreviations
private Set<String> names = new HashSet<>();
private Set<String> abbreviations = new HashSet<>();
// All coins must have one of the following ISO currency codes as the 'unit' field.
private final Set<String> allIsoCurrencyCodes =
Set.of("CLP", "GBP", "EUR", "CAD", "USD", "XXX" /* , ... */);
private List<Coin> allCoins = new ArrayList<>(
List.of(createCoin("Pesos chilenos", "CLP", BigDecimal.ONE, "CLP")));
private List<Coin> unmodifiableListOfAllCoins =
Collections.unmodifiableList(allCoins);
public Coin createCoin(String name, String abbreviation, BigDecimal value, String unit) {
if (!names.add(name))
throw new IllegalArgumentException("Name already exists: " + name);
if (!abbreviations.add(abbreviation))
throw new IllegalArgumentException("Abbreviation already exists: " + abbreviation);
if (!allIsoCurrencyCodes.contains(unit))
throw new IllegalArgumentException("Coin unit is not a recognised ISO currency code: " + unit);
Coin coin = new ConcreteCoin(name, abbreviation, value, unit);
allCoins.add(coin);
return coin;
}
public Collection<Coin> allCoins() {
return unmodifiableListOfAllCoins;
}
}
I am trying to do the following redundant code - copying a Class FeedDBTableRow's object into a Feed object - where they mostly have overlapping set of variables, and I am trying to copy those common set of variables. Is there a design pattern or an annotation processor that helps me reduce these (potentially bug-prone) lines of code?
The reason for doing this basically I want to use Retrofit with GSon and Realm (and Realm due to its own construction, needs the Pojo to extend from RealmObject class, while doing this creates a GSON error - it is documented at several places)
public static Feed getFeedFromDBFeedRow(FeedDBTableRow f){
Feed x = new Feed();
x.setId(f.getId());
x.setText(f.getText());
x.setTime_created(f.getTime_created());
x.setTime_modified(f.getTime_modified());
x.setComments_count(f.getComments_count());
x.setLikes_count(f.getLikes_count());
x.setFeed_type(f.getFeed_type());
x.setObj_id(f.getObj_id());
x.setImage(f.getImage());
x.setUser_name(f.getUser_name());
x.setUser_earthmile_points(f.getUser_earthmile_points());
x.setLiked(f.isLiked());
x.setCommented(f.isCommented());
x.set_private(f.isIs_private());
x.setUrl(f.getUrl());
x.setFeed_creator_id(f.getFeed_creator_id());
return x;
}
My Feed class is:
public class Feed {
int id;
String text;
Date time_created;
Date time_modified;
int comments_count;
int likes_count;
String feed_type;
int obj_id;
String image;
String user_name;
String user_earthmile_points;
boolean liked;
boolean commented;
boolean is_private;
String url;
int feed_creator_id;
public Feed() {} // required for being Parcelable
}
And the FeedDBTableRow class is :
public class FeedDBTableRow extends RealmObject{ // having this necessity to extend RealmObject is the source of all problem, but I have to do this, hence two classes with similar composition
private int id;
private String text;
private Date time_created;
private Date time_modified;
private int comments_count;
private int likes_count;
private String feed_type;
private int obj_id;
private String image;
private String user_name;
private String user_earthmile_points;
private boolean liked;
private boolean commented;
private boolean is_private;
private String url;
private int feed_creator_id;
}
Take a look at Apache BeanUtils: http://commons.apache.org/proper/commons-beanutils/javadocs/v1.9.2/apidocs/index.html
In particular, BeanUtils.copyProperties() might be something you find useful.