Help constructing a class with ArrayList as a parameter - java

Ive been trying to work this out for a few hours now, but am stuck, hence I am coming here for some help.
N.B. I am using BlueJ, to construct these classes, as im still learning.
What I am trying to do is create a PlayList which has a two parameters: name and a ArrayList of tracks.
It then creates a playlist and copies the tracks from the list (in order) onto the playlist; but I dont want any help with this part, as of yet.
My issue is I am unsure how to call the ArrayList when constructing the PlayList.. Because the specified type is of .
public class PlayList
{
private String myName;
private ArrayList<Track> myTracks;
private int myDuration;
public PlayList(String name, ArrayList<Track> tracks) {
name = myName;
myTracks = new ArrayList<Track>();
for (Track t : tracks) {
myTracks.add(t);
}
}
}
What happens, in BlueJ, is when I construct a new PlayList class, it provides an empty field box for String name, and for ArrayList tracks. String name is fine, as I can simply put "anything" but am stuck as to the ArrayList tracks?
I know this is probably isnt a very specific question, but I am still learning.

sunadorer's response should answer your direct question. I have some general remarks about naming conventions for the fields in your class and the parameters of your constructor.
I would not prefix your fields with 'my'. It is a bit of a matter of style, but I would not have much against using the same names for the constructor parameters. You can distinguish between the parameter and the field by using this.name when referring to the field.
Also, using ArrayList here seems unnecessarily restrictive: you could use the more general List interface (which ArrayList is just one implementation of, so you don't have to touch PlayList if you want another kind of List later o):
public class PlayList {
private String name;
private List<Track> tracks;
private int duration;
public PlayList(String name, List<Track> tracks) {
this.name = name;
this.tracks = new ArrayList<Track>(tracks);
}
}

The constructor of your PlayList wants an object of type ArrayList filled with elements of type Track. So to create a PlayList you must provide an already created one.
It depends on your surrounding of the call, maybe you already build a list there and can just put it into your PlayList constructor, but you need something like this anywhere:
// Create an empty list
ArrayList<Track> tracks = new ArrayList<Track>();
// Add a track. e.g. when receiving a gui event
tracks.add(track); // track was created with new Track()
Or maybe you don't need/want lists outside of PlayList objects. You could use PlayList objects to manage and encapsulate those, by changing the constructor to only create an empty list on its own and allow others to add tracks to it via an addTrack method.

Related

How to construct a user(/input)-specified number of objects

I'm currently doing an intro level undergrad CS course (learning basics of 'program'&'class' building using Java).
The relevant part of my personal (&job related) project: I have a list of zip codes associated with One county.
I'm gonna define a class called 'County'. Then I'm gonna use this class to construct an object of type County, called 'middlesex'.
ie: County middlesex = new County();
Now, in this object, I want to construct a number of objects of class-type ZipCode.
ie: ZipCode objName = new ZipCode();
(Each such ZipCode object is gonna contain certain instance data).
My problem is this. Assume that I don't know how many zipcodes are contained in the Middlesex county. However, I have a .txt file that contains just a list of all the zipcodes of Middlesex county.
Let's say there are n number of zipcodes in this list.
In the object 'middlesex', of class-type 'County', I want to set up a loop. This loop will scan each zipcode in the list, then construct an object of class-type ZipCode for each zipcode.
Thus the loop may go thru n iterations, and construct n objects of type ZipCode.
Thus, for every iteration of the loop, a unique object-reference-name must be created (corresponding to the particular zipcode in the list).
Part of this problem (but distinct and optional), is that I want to know how (if possible), I can set up a structure that allows an inputted (scanned) string to be used as the name of an object-reference.
I apologize if I've made incorrect terminology use. I know that many are gonna suggest arrays. I haven't learned about them yet, but I gotta read about them over this weekend for school. I'm just gonna try to figure this out for a day or two, and then just move on to using arrays to perform this task.
So, if I've made any sense to anyone, is what I'm trying to do possible without arrays?
Thank u.
You're describing a very basic scenario, one where one object contains (possibly) many references to objects of a 2nd type, what we call a constructor called "composition" where the relationship here is a "has-a" relationship, County has-a (or has-many) zip codes
As opposed to using inheritance to wrongly try to solve this, the "inheritance" relationship or the "is-a" relationship -- County is not a zip code and zip code is not a county.
The code to create this can be very simple, something like:
import java.util.ArrayList;
import java.util.List;
public class County {
private String name;
private List<String> zipCodes = new ArrayList<>();
// constructor that takes county name
public County(String name) {
this.name = name;
}
public void addZipCode(String code) {
zipCodes.add(code);
}
// ..... more code
If a zip code is a single String, then no need to create a new class for this. If however it is more complex and holds more data than a single String, then create a class for ZipCode, and change the code above to something like
import java.util.ArrayList;
import java.util.List;
public class County {
private String name;
private List<ZipCode> zipCodes = new ArrayList<>();
// constructor that takes county name
public County(String name) {
this.name = name;
}
public void addZipCode(ZipCode code) {
zipCodes.add(code);
}
// getters, setters, a decent toString method override...
Where ZipCode could contain....
public class ZipCode {
String code;
// other fields if needed....
public ZipCode(String code) {
this.code = code;
}
// ....
then when reading in data, create your County objects and as each Zip code is read in, add it to the appropriate County object using the addZipCode(...) method.
zipCode is an object of Type ZipCode then what are its fields? Think of the reasons for making it an object and not a variable
"Thus the loop may go thru n iterations, and construct n objects of type ZipCode"
Unforutnality this is not possible without making the use of Arrays
"structure that allows an inputted (scanned) string to be used as the name of an object"
Nope can do that.

Java football team map that references List of Team objects

I'm new to Java and currently stuck on an assignment question.
I need to create a method for the LeagueAdmin class called addTeam(), which takes two arguments and returns no value. I'm given the header: public void addTeam(String division, Team team)
The method should check to see if a list for that division already exists in the teams map.
If the list exists, then the new Team should be added to the existing list of teams for that division.
If the list does not exist, then a new empty list of Team should be created and the new Team should be added to it, then a new key-value pair should be created in teams with division as the key and the new list as the value.
My code so far is as follows:
import java.util.*;
public class LeagueAdmin
{
public Map<String, List<Team>> teams;
/**
* Constructor for objects of class LeagueAdmin
*/
public LeagueAdmin()
{
this.teams = new HashMap<String, List<Team>>();
}
}
I have separate class as follows:
public class Team
{
private String name;
private String division;
private int won;
private int drew;
private int lost;
// no need to record points as = 3*won + drew
/**
* Constructor for objects of class Team
*/
public Team(String aName, String aDivision)
{
name = aName;
division = aDivision;
// no need to set won, drew and lost to 0
}
}
If anyone can give me some pointers that would be great,
Thanks, Kat
Before answering your question, a couple of suggestions.
always declare local variables and fields as final when possible
always format your code. Seems superfluous but it's something I don't see done often
initialize final fields in-line, not inside the constructor, if possible
don't expose fields, which are part of implementation details
Edit: being that maybe you need a simplified version, I'll also add that, but keep reading all my answer, it's fun!
Follow the comments inside the code to understand the flow.
public class LeagueAdmin {
private final Map<String, List<Team>> teams = new HashMap<String, List<Team>>();
public void addTeam(final String division, final Team team) {
// We retrieve the team list, if any
List<Team> list = map.get(division);
// We check if the list was already there, or we have to create a new one
if (list == null) {
// The list is null, we need to insert a new one!
list = new ArrayList<>();
map.put(division, list);
}
// We add the team to the list
list.add(team);
}
}
Now, for a more "new" and simplified version, which does the exact same thing as the one above, the implementation would be
public class LeagueAdmin {
private final Map<String, List<Team>> teams = new HashMap<String, List<Team>>();
public void addTeam(final String division, final Team team) {
teams.computeIfAbsent(division, __ -> new ArrayList<>()).add(team);
}
}
Since Java 8, the Map interface exposes a new method
computeIfAbsent(Key, Function)
What this does is
try to get the value associated with the inputted key
if no value found, use the Function argument to associate a new one
return the associated value
Also, you'll ask yourself what __ -> is.
Well, __ is just a valid variable name, used to say "hey, I don't need that"
The -> (arrow) is part of a lambda expression, which is basically an in-line function
The Answer by LppEdd suggesting computeIfAbsent is correct, but perhaps not what your course instructor is looking for. She/he probably wants you to more coding than that, as we did do in real work before that new method was added recently.
The old-fashioned of the addTeam(String division, Team team) method you need to add to LeagueAdmin would ask the map if it has a key for the division string. If no such key, add one, and put as its value a new empty List of teams to which you have added the team in question. If there is such a key, retrieve its value, a List, and then add the team in question to that list.
As a homework assignment, to do the learning you need to struggle with this a bit rather than copy some existing code. Study the JavaDoc for the Map and List interfaces. Follow my prose above as pseudo-code to walk you through the logic. Be sure you understand the ideas behind each class, especially the key-value pairing of a map (also known as a dictionary or an associative array). Draw a diagram on paper, imagining each step I outlined above.
So a league object holds a Map object. The map holds a collection of keys, each key being a division name (a String in your situation, more likely a Division class in real work). Being a key in a map means each division name will lead you to a List object, a collection of teams. A List keeps items in the order in which they are added. A Set would like work just as well here, by the way.
Note in this diagram how one of the List objects is empty, meaning it has not yet had any teams assigned. An empty list is not nothing; an empty list is something. The empty list is still a valid object, just like a fruit basket without any fruit in it is still a basket. If no list, empty or otherwise, has yet to be assigned to a key in a map, the key points to null where null really does mean “nothing at all”. We see in this diagram that the “division-z” key in the map has not yet been assigned any List object at all, so it points to nothing, null.

inheritance and objects in ArrayList

Okay. I'm fairly new in this Java thing, but i'm desperately trying to learn. I've come upon somewhat of a deadend. I'm making an inventory program as part of school and i have a superclass Items with 4 instance variables. No problem there. I have 4 subclasses, two of which is mandatory Food class, which have a futher 2 variables and Nonfood class, which have one more variable. My problems is this.
Right now i'm working with an ArrayList (this is what i know so far) but i'm seriously considering working with a map or a linkedMap.
I have based my ArrayList on my superClass Items, but i'm having trouble getting my subclass variables into my ArrayList. Any idea how that's done. Using relative simple solutions (remember i'm new at this)
I have not yet got my id working. I've, in the spirit of the shop terminology, called it barCode. It's part of my Superclass, and i can't seem to initialize it in my main class.
//constructer from superclass
public Items (int barCode, String itemName, String itemSupplier, double itemPrice, int stock)
{
this.itemName = itemName;
barCode = GenerateBarCode();
this.itemSupplier = itemSupplier;
this.itemPrice = itemPrice;
this.stock = stock;
// getter method for barCode
protected int getBarCode()
{
return barCode;
}
// method for generating barcode
private int GenerateBarCode()
{
Random barCode = new Random();
int barCode1 = barCode.nextInt(100000);
return barCode1;
}
If any more code i needed, let me know. I'm working on getting it a bit prettyer.
You have a local variable barCode in your constructor, and it is hiding your instance member also called barCode. Parameters are really local variables, and locals get precedence over fields. This local variable gets the random value, and then disappears at the end of the constructor, like all locals, leaving your field also called barCode with its original value.
You could fix it by changing the parameter to be called barCodeIn, or changing the statement to this.barCode = GenerateBarCode()
However the real solution is to remove the barCode parameter from the items constructor.
Since you are generating it with the GenerateBarCode() function, you don't really need to pass it in from the outside.

How to use an object's class variables to identify an object in java?

I created a class and made 57 objects from it, each one has specific ID number.
Can I create a method which returns an object using an ID as the argument?
For example, assume the name of my class is Things and I made two object from it called apple and dog, they have IDs 1 and 2.
Things.java:
class Things {
private String name;
private int ID;
public Things(String name, int ID) {
this.name = name;
this.ID = ID;
}
}
Main.java:
class Main {
public static void main(String[] args) {
Things apple = new Things("apple", 1);
Things dog = new Things("dog", 2);
}
}
in this example I want to create a method in class "Things" which returns object apple if I use 1 as argument and object dog if I use 2 .
You cannot identify objects by a particular property unless you store it in a special repository
You can create a ThingRepository and can get specific Things by the id.
public class ThingRepository {
private Map<Integer, Things> thingsRepository = new HashMap<>();
public void addThing(int id, Things things) {
thingsRepository.put(id, things);
}
public Things getThingById(int id) {
return thingsRepository.get(id); //Can return null if not present
}
}
The addThing method need not explicitly take the id. If you add a getter to Things, then it can be simplified to
public void addThing(Things things) {
thingsRepository.put(things.getId(), things);
}
Couple of problems you need to address:
Each created Things object has to be added to this somehow (either the caller needs to add or there must be some other wrapper/factory that must do this).
Once a Things is not needed, it must be removed from the above map, else it can lead to memory leak.
Btw, shouldn't Things be named as just a Thing?
There are two aspects here:
you need some sort of data structure that remembers about created objects, and allows you to access them by id, for example a simple Map<Integer, Things>. Each time you create a new Things (should better be called Thing, shouldn't it?!), you go thatMap.put(newId, newThing).
if you want that data to "survive", you would have to somehow persist it (like writing data to a file, database, ...)
If you use Intellij for example press: alt + insert and choose getters/setter.
If not just write your own getters/setter ;).
Like here: https://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html
But basically if you want to look for Thing with particular Id you need to store somewhere them for example in ArrayList, then iterate through it and if your find element with that Id just return it.
1) Create new ArrayList
2) Iterate through
3) If you find Thing with Id you want, return it.

Storing elements that have multiple elements

What is the best way to store an element that has multiple elements? As in a 6d array.
I have seen something along the lines of ArrayList(ArrayList(ArrayList(ArrayList))), but don't have a clue as to how or mostly why it would be configure as such or how to access the elements!
As an example, I want to create an array(list) that stores the following information:
house id, house number, street name, residents, owner first name, owner last name
I would like to be able to sort and search on anyone of the sub-elements in the main record element.
What I have done is create an arraylist that contains an arraylist for each of these. Basically I have a class called HouseArray that has a method called CreateArray. From my class GUI, I have
houses = new HouseArray();
houses.CreateArray();
In class
HouseArray, my method CreateArray has
ArrayList<Integer> entryID;
ArrayList<Integer> houseNum;
ArrayList<String> streetName;
ArrayList<Integer> residents;
ArrayList<String> firstName;
ArrayList<String> lastName;
entryID = new ArrayList();
houseNum = new ArrayList();
streetName = new ArrayList();
residents = new ArrayList();
firstName = new ArrayList();
lastName = new ArrayList();
and then I use an AddEntry method that puts data into each arraylist.
this.entryID.add(12345);
this.houseNum.add(9876);
this.streetName.add("My Street");
this.residents.add(4);
this.firstName.add("John");
this.lastName.add("Jones");
I am at a loss at how I would be able to sort this mess and keep the entries synchronized without manually writing a lot of coding to do it all. Also, I want to be able to sum the number of residents that live on a particular streetName or total the number of residents that live in houses owned firstName or lastName.
Am I on the right track or is there a better way to do this?
Teaching myself java, so not sure if this counts as homework.
As an example, I want to create an array(list) that stores the
following information:
house id, house number, street name, house color, owner first name,
owner last name
the best approach is to create a Class name it House and have these attributes as its state.
class House {
private long houseId;
private long hNo;
private String streetname;
private String color;
private String owner;
private String firstName;
public House(long houseId, long hNo, String streetName, String color, String owner, String firstName){
//initialize your instance variables here
}
public void setHouseId(long houseId){
this.houseId = houseId;
}
//do the same thing for reamining attributes
//getters and setters for all the attributes.
}
now, create a java.util.List which holds House Object.
List<house> houseList = new Arraylist<>();
//and populate the list with house objects.
House house1 = new House(123,223,"Bond Street", "Green","James Bond", "James");
list.add(house1);
This approach is more Object-Oriented way of doing things, as House represents an Object which has state and behaviour.However, if you want to sort your House elements in your arrayList you will have to override equals and hashcode methods.
I think another approach would be create House class with those properties.
Instantiate house object and add to arraylist. You may override equals and hashcode method to perform sorting.
Example:
class House{
int houseNum;
String street;
...
//get/set for above properties.
}
And add it to list:
House houseObj = new House();
list.add(houseObj);
Where exactly have you seen along the lines of ArrayList(ArrayList(ArrayList(ArrayList)))?? This looks wierd. Never have such kind of design..
If you want to store multiple fields, then create a custom class with all those fields, and have an ArrayList of that class.
For e.g: -
class House{
private int houseId;
private int houseNumber;
private String streetName;
private String owner;
private String firstName;
// Constructors
// Getters and Setters
}
And create an ArrayList of that class: -
List<House> myHouses = new ArrayList<House>();
then, to add an object to your list, just use normal add method: -
myHouses.add(new House(houseId, houseNumber, ....));
And to access elements: -
for (House myHouse: myHouses) {
System.out.println(myHouse.getHouseNumber());
}
I think you're not just new to Java. You're new object-oriented programming in general. Are you a student and this is some sort of homework? If it is, please tag it as such.
For your particular data, your class should be House.
public class House
{
int entryId;
int houseNum;
String streetName;
String houseColor;
String firstName;
String lastName;
}
Note that in my sample code above, I'm assuming you know enough of java to add the access modifiers like private, public, etc. and know enough about how to add getter and setter methods, (e.g. getEntryId(), setEntryId(int entryId), etc.).
If your objects are actually more complex, you might also be better off creating classes like Address, Person, etc.
Then with this class, you do create a list:
List<House> houses = new ArrayList<House>();
House myHouse = new House();
// insert whatever data you want into "myHouse"
houses.add( myHouse );
To sort the objects in a list, because it's in a List, it's part of Java's Collection Framework. You can use the Collections.sort() method to sort it. But first you need to understand how it works.
I would suggest you the following pages:
Object-Oriented Programming Concepts
Java Tutorial: Collections
Object Ordering
I am at a loss at how I would be able to sort this mess
First, others have already pointed out that you should create a House class to organize "this mess".
To sort it, implement the Comparator interface, e.g. (assuming your House class has a getEntryID method):
public class HouseIDComparator implements Comparator<House> {
#Override
int compare(House house1, House house2) {
return house1.getEntryID().compareTo(house2.getEntryID());
}
}
This comparator can be passed to Collections.sort(List<T>, Comparator<? super T>) for sorting. (Note that there is also a sort method with one argument, for lists of types that implement the Comparable interface. However, you probably do not want your House class to implement that, since it is not obvious on what basis houses should be compared, and you yourself might want to use several different ones.)
As for summing up values, the best way is to loop over all elements in the list and sum up manually.

Categories