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.
Related
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.
My question which of the following examples represents the right practice ?
What are the advantages and downsides of these approaches.
Is there another(right) way to achieve this?
Let's say I have class
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String print() {
return this.name;
}
}
And use of class like:
public static void main(String[] args) {
List<Person> people = new ArrayList<Person>();
people.add(new Person("Jane Doe"));
System.out.println(people.get(0).print());
}
And then another way to do this:
public class Persons {
private ArrayList<String> persons;
public Persons() {
persons = new ArrayList<String>();
}
public void putPerson(String name) {
persons.add(name);
}
public String print(int id) {
return this.persons.get(id);
}
}
And use of that:
public static void main(String[] args) {
Persons persons = new Persons();
persons.putPerson("John Doe");
System.out.println(persons.print(0));
}
EDIT:
Assume I have 10 000 of these persons.
Is there any downside to creating 10,000 instances of the class?
I would prefer the first way because there is a rare need to create a wrapper class for keeping a collection (like Persons -> Person). It makes sense if the class Persons gets renamed to a Company/Community, which contains a List of workers/persons and provides specific operations over this list.
public String showAllMembers() { ... }
public void notifyAllMembers() { ... }
Also, the second way breaks the Single responsibility principle. It shouldn't take care about printing a person, the class is responsible for adding/removing them. The Persons can provide to you a specific Person, then you have to call a method print() on a given instance:
Persons persons = ...;
persons.getMember(10).print();
Lets say i have 10 000 of these persons. Is there any downside to create 10 000 instance of class?
In any case, you will have to create 10000+ instances. Consider,
10000 Persons + a List
10000 Persons + a Persons + a List
The first one is more object-oriented than the second, which becomes apparent as soon as you start adding more properties to a person.
For example, consider adding a date of birth to a person. When you have class Person, you modify the class, and everyone who has access to it will be able to get it. You will also be passing the date of birth with the Person object, so any method that takes Person as a parameter will have access to that person's date of birth:
static void displayPerson(Person p) {
// Here, we can print both the name and the date of birth / age
}
public static void main(String[] args) {
...
displayPerson(people.get(0));
}
The second approach would require adding a parallel collection to the Persons class. All users of Persons would get access to date of birth, but unless a method takes the full collection as a parameter, it would have access to only the properties that the caller takes from the collection:
void displayPerson(String name) {
// Here, we have no access to person's date of birth
}
public static void main(String[] args) {
...
displayPerson(persons.print(0));
}
In Java, the first approach is the one to go with. It is more in accordance with the OOP way of doing things.
While there is nothing structurally wrong with the second, it doesn't follow the OOP architecture. You may do this kind of operation in C.
In the first approach, you create a Person class which defines what a person is - its properties, methods, etc. This is the object in Object oriented programming. When you need a Person, you then instantiate one and add it to a list of people.
In the second, you create a array, essentially. You can then create an instance of it and fill in the properties you want. However, I see the following drawbacks for this approach:
The object you're adding to the class doesn't exist anymore. Nowhere have you defined what a person is and what properties it has. These properties only exist in the values you add to the array. This can get very confusing and risky after a while.
No getters and setters. Every operation to retrieve a specific property and update it will result in very complex and redundant iterations on your array. In addition, your class can potentially have a very large number of properties, and every time you want to update a property, you'll have to be very careful to get the right index of that property in the array. It's a recipe for disaster.
Also, a putPerson method which just adds a value to the array? Cringy.
Short answer: don't do the second way, in Java, ever.
In my opinion example A is much easier to understand than B hence I would say code readability and maintainability wise it is better.
Reason is that for example B the persons structure actually involves composition of another structure ArrayList to accomplish generics which in example A, you have achieve it by declaring List<Person>.
Example B is also less flexible than A, because it is always a collection whereas example A you can simply use it as a Person and just plug it into different data structures available in Java. Example if you want to keep track of unique person, you can easily come out with a map that is keyed by <name, Person>, whereas example B would not be as clean because you will be doing something like <name, Persons> where each persons would only contain 1 person. Hence extensiblity wise may not be as great as the other one.
Also to me, A is more of the traditional way of doing object oriented because you are representing a real world object as a class whereas B is really just a wrapper of an object.
Obviously there can be a lot of arguments to this, but I'm happy with others input and critic about this answer.
I am trying to learn some foundational ways to manipulate certain aspects of coding that stray away from single use and make something more "dynamic" that can kind of build itself on the fly.
For example of what I would like to accomplish, which I believe would consist of using some type of empty array of an object and a loop. I just don't know how to write it.
Lets keep it basic and say I have a Person Class.
public class Person
{
String name;
String age;
}
So in my TestDrive I would just get a simple user input to gather information on that person.
Such as...
import javax.swing.JOptionPane;
public class PersonTestDrive
{
public static void main(String[] args)
{
String name;
String age;
name = JOptionPane.showInputDialog(null, "Enter your name");
age = JOptionPane.showInputDialog(null, "Enter your age");
Person human = new Person();
human.name = name;
human.age = age;
JOptionPane.showInputDialog(null, "Would you like add another entry?");
/* At this point it would loop if the user wanted to add another entry.
I would just wrap it all in while loop that just checked if the user said yes or no.
However, if they do choose to add another entry
"IF" a human object already existed it would create a
new human2 object, and then human3, etc. */
}
}
It sounds that all you need is a collection of objects, such as ArrayList<Person>.
"human" is a name of your variable, and at compile time you don't know how many other variables there can be so you cannot refer to them in the code using "human2", "human3" and so on. You can create these variables, but they may be nulls and your input will also be limited to how many variables you have. Another problem would be keeping track of what variable to assign to next.
With List<Person> list you can do list.get(2) to get third object (it will thrown an exception if there are few than 3) or list.size() to check how many objects were created so far.
Here is some more information about Java collections: http://docs.oracle.com/javase/tutorial/collections/
I am currently just getting into Web services as it is new to me. I have put together a sample one returning animal type.
public class AnimalTypeService {
public String animalType(String animal) {
String animalType = "";
if ("Lion".equals(animal)) {
animalType = "Wild";
} else if ("Dog".equals(animal)) {
animalType = "Domestic";
} else {
animalType = "I don't know!";
}
return animalType;
}
}
However, I would now like to take several string/parameters. For instance someone who enters in a name, lastname, age, birthday. Can someone give me an example on how I could take in a set of parameters such as these and write them into a xml doc format?
For taking in multiple parameters you have three options:
1) You could create a class (human for example), which contains the instance variables name last name, age, and birthday.
2) You could pass in the parameters as an ArrayList or as an Array. However, you then have to be careful that the ordering of the parameters fits what you need (so that you don't read in a last name as a birthday for example).
3) You can pass in the parameters as a map, with a key being "name" and a value being "steve" for example. Then the method could search for certain keys and find the values associated with those keys.
In regards to writing them into an xml doc format, i would suggest looking up DOM objects, as they make writing xml docs very simple. http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/ provides a great tutorial/example
For my homework, we've been tasked with creating:
Person class with variables firstName, lastName, streetAddress, zipCode and phone.
CollegeEmployee extends Person and adds ssn, salary, and deptName.
Faculty extends CollegeEmployee by adding a boolean tenure.
Last but not least, Student extends person by adding GPA and major.
Everything looks good displaying to screen, and I'm moving on to the next part of the assignment which is to create 14 records (7 students, 4 employees and 3 faculty) in an array.
3 different classes, with multiple data types, and I cannot for the life of me figure out how to populate an array with this. This is the first array I've created that's not been completely integer. The Java Tutorials didn't give me anything, and while Java: Generic Static Multidimensional Arrays has some great information, it's a little more than I can wrap my head around right now.
I'd initially thought of creating array[14][10] -- fourteen variables each for ten objects -- but I can't mix data types. That's where I got lost.
Anyone have any suggestions on how to design this array and be able to display the values from it afterward?
Any hints and suggestions would be appreciated!
Thanks.
From what I understand, no need to get fancy with multi-dimensional arrays.
1) Create an array that takes Person instances.
Person [] myPeeps = new Person[14];
2) Create a print method on Person, which subclasses override to print the relevant info.
Because your array expects Person instances, you can put instances of any subclasses of Person, because subclasses always have an is-a relationship with their superclass.
Because Person has a print method, you can call print on anything you pull out of the array. Subclasses provide their own implementations so they can print their relevant data. That way, you don't really care about which subclass any particular instance is; the correct print implementation for the instance is invoked at runtime.
You don't need a multidimensional array. You can make an array of Person objects.
Person[] people = new Person[14];
people[0] = new Student();
people[1] = new Employee();
.
.
.
You could also create a Person[] array, just as you would an int[] array. e.g.
Person[] people = new Person[14]
You can then add people to the Array like this:
people[0] = new Student();
people[1] = new CollegeEmployee();
people[2] = new Faculty();
If you want to check what type of person is in each index you will want to use instanceof. Try looking here for more help
One example of using instanceof is:
if(people[0] instanceof Student){
System.out.println("This person is a student");
}
Or try using generics.
You could create an ArrayList<Person> and can then add any type of person to this ArrayList.
e.g.
ArrayList<Person> peopleList = new ArrayList<Person>();
//People can be added like this
peopleList.add(new Student());
peopleList.add(new CollegeEmployee();)
Again you are able to use instanceof to check which type of person is in each index!
Also if you never write
Person person1 = new Person();
In your code then consider making your class abstract.
To start:
Person[] myArray = new Person[14];
This is essentially why object oriented programming is so wonderful. If you'll notice, all Faculty, CollegeEmployee, and Student are a subset of type Person. Because of this, you can have them all contained in the same dataset if it is declared as type Person.
Person[] array = new Person[14];
You can add all of your objects to that array; however, be careful. When you go to use the elements of the array Java now only knows that each has the methods that a Person does - so therefore you can only make use of firstName, lastName, streetAddress, zipCode, and phone from these elements unless you cast the objects after they are retrieved.
Since they are all of type Person, why not use a Person array?
Person [] people = new Person[14];
You can safely add all types of Person to this array, however you can only treat them as Person (without casting). To have each subclass output customized details, and add this method in Person
class Person {
void print() {
// default Person printing
}
}
and override this method in each subclass to print its member variables:
class Student extends Person {
void print() { // <-- note same method signature!
// print "I'm a Student", GPA, major
}
}
and when the array is populated:
for (Person p : people) {
p.print(); // delegates to print method associated with the underlying type
}
Check out the inheritance tutorial
The class Person is a common superclass to all the types of the objects you want to store in the array. You can create the array based on that common supertype. Then you can access methods that are defined in that tpe on all elements of the array, regardless of the actual type -- the behavior is as defined in the actual type (look up inheritance for java if this is not clear).
If you need specific behavior based on the actual type, you need to cast the array element to the concrete type (you can determine it using instanceof, for example)