I know there are standard way by add a constructors to the class. But for classes with object superclass (has no-argument constructor) I tend to find using a temporary object simpler. Is there any down side for such an act.
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
// data available in two separated arrays
String[] dName = {"Sam","Ben","Joye","Sarah","Tim","Lucy","Jack"} ;
int[] dAge= {10,52,53,15,12,60,21};
// Array list to put the data in
ArrayList<Person> personList =new ArrayList<Person>(7);
for (int i=0;i<dName.length;i++){
Person tempPerson = new Person();
tempPerson.name= dName[i];
tempPerson.age= dAge[i];
personList.add(new Person());
personList.set(i,tempPerson);
tempPerson=null; //removes the reference
}
for (int j=0 ; j<personList.size();j++){
System.out.println(personList.get(j).name+" age is "+personList.get(j).age );
}
}
}
class Person{
String name;
int age;
}
the output
Sam age is 10
Ben age is 52
Joye age is 53
Sarah age is 15
Tim age is 12
Lucy age is 60
Jack age is 21
You should avoid statements that do nothing - an optimization would be to do
for (int i=0;i<dName.length;i++){
Person tempPerson = new Person();
tempPerson.name= dName[i];
tempPerson.age= dAge[i];
personList.add(tempPerson);
}
No need to first add the person to later replace it
No need to null the reference - the list will keep the reference to the temp object in any case.
Instead of setting values directly you could use setters (setName() instead of .name = )
If you'd use setters, you could implement a Builder pattern:
like this:
public Person setName(String aName) {
name = aName;
return this;
}
Resulting in something like
personList.add(new Person().setName(dName[i]).setAge(dAge[i]));
Then again - the two value constructor will probably be the easiest of all - and it don't matter that the super class doesn't have a constructor:
public Person(String aName, int aAge) {
name = aName;
age = aAge;
}
//You can have more than one constructor
public Person() {
}
and then
personList.add(new Person(dName[i], sAge[i]));
You should use a constructor for Person. Then you have just one call in your for-loop:
personList.add(new Person(dName[i], dAge[i])
Also, in your implementation, you are doing the necessary work twice, because you call personList.add(new Person()) and then you call personList.set(i, temPerson). If you don't want a constructor in your Person-class, a call of personList.add(tempPerson) for example would be enough.
Not really,
you could maybe make use of java8 streams, but why make your life harder, it wouldnt add anything new
Related
Let's suppose we have 1 class called GroupOfStudents, which has one property named vectorOfStudents. So, that class looks like this:
public class GroupOfStudents{
public Vector<Student> vectorOfStudents = new Vector<Student>();
public GroupOfStudents(Vector<Student> vectorOfStudents) {
this.vectorOfStudents = vectorOfStudents;
}
}
Ok, simple, right ? Also, we have one class called Student and let's say it just has student's name as property.
public class Student {
public String name;
public Student(String name) {
this.name = name;
}
}
Now, let's create 2 groups without any students.
Vector<Student> emptyVectorOfStudents = new Vector<Student>();
GroupOfStudents group1 = new GroupOfStudents(emptyVectorOfStudents);
GroupOfStudents group2 = new GroupOfStudents(emptyVectorOfStudents);
And, of course, let's give group1 for example 1 student, called "Luke".
Student student1 = new Student("Luke");
group1.vectorOfStudents.add(student1);
Let second group remain empty. When I want to output names of students of both groups, for some reason, group2 has also student1 in its vector.
for(Student s: group1.vectorOfStudents) {
System.out.print("Name: " + s.name + " ");
}
System.out.println("");
for(Student s: group2.vectorOfStudents) {
System.out.print("Name: " + s.name + " ");
}
Output is:
Name: Luke
Name: Luke
And it should be:
Name: Luke (because second group has no students)
Any reason why this happens ?
it is not even written in code that it should
Yes, it is, here:
Vector<Student> emptyVectorOfStudents = new Vector<Student>();
GroupOfStudents group1 = new GroupOfStudents(emptyVectorOfStudents);
GroupOfStudents group2 = new GroupOfStudents(emptyVectorOfStudents);
Both group1 and group2 use the same Vector. If you want them to have separate vectors, give them separate vectors:
GroupOfStudents group1 = new GroupOfStudents(new Vector<Student>());
GroupOfStudents group2 = new GroupOfStudents(new Vector<Student>());
Note that your GroupOfStudents code is creating a Vector already on construction, but then throwing it away to use the one it receives as a constructor parameter:
public class GroupOfStudents{
// Creates a new Vector when an instance is created
public Vector<Student> vectorOfStudents = new Vector<Student>();
public GroupOfStudents(Vector<Student> vectorOfStudents) {
// Throws away the Vector created above and uses the one from the parameter instead
this.vectorOfStudents = vectorOfStudents;
}
}
Probably best to just ditch the parameter and not pass in a Vector at all, either:
public class GroupOfStudents{
public Vector<Student> vectorOfStudents = new Vector<Student>();
public GroupOfStudents() {
}
}
or
public class GroupOfStudents{
public Vector<Student> vectorOfStudents;
public GroupOfStudents() {
this.vectorOfStudents = new Vector<Student>();
}
}
First of all, are you sure you want to use a Vector? The documentation of Vector itself states that:
If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
Second, if you want to pass the Collection to your constructor class(es), you may want to copy the Collections before storing them in a local field (e.g. through Collections.copy(...)). The Java API is suboptimal designed here. Not all Collections define a copy-constructor, and Cloneable is not an option. So we have to work with what we have got. But hey! If everything were easy, it would be boring, wouldn't it? :)
I have a student object that can hold name and mark.
public class Student{
Public String name;
Public int mark;
public Student (int argMark, String argName)
{ mark=argMark; name=argName;}
}
when I create a student as :
Student john = new Student(70, "John");
I need to change the mark later while keeping the previous marks
Student temp = john;
temp.mark = 60;
when I print them out they both have 60 marks
System.out.println(temp.mark);
System.out.println(john.mark);
the system shows the answer of : 60 for both of them
I know I can extend a class and have a method for get, set methods and override it, but this is not acceptable for my assignment. Is there any other way to do this?
You can create copy constructor and by doing that you can have new reference with the same attribute values in your temp. Currently John and Temp have same reference and change in one will get reflected in other.
public Student (Student student) {
this.mark = student.getMark();
this.name = student.getName();
}
Few suggestions,
Use getter and setter methods instead of accessing variables directly.
Follow naming conventions. i.e. start variable name with lower case.
When you say
Student Temp = John; // <-- typo for John
you assign a reference to the same instance that Jhon references. Based on your question, you expect a second instance. Something like
Student Temp = new Student(John.Mark, John.Name);
Also, by convention Java variable names start with a lower case letter.
I am working on a Java app for a school project where we have to enter user information: Name, Student ID and their points. How can I store all the data for each user on an ArrayList (or an Array or really whatever type) so I can keep track of all the data.
Example:
John Doe - 401712 - 20 points
Jack Young - 664611 - 30 points
The I want to be able to call methods like setPoints to change the point values for whatever the student selected is.
Here's the problem: How can I link the ArrayList together. If I have three ArrayLists, how does Java know what name, student id and points are associated together?
All the ArrayLists are stored in a class called Data.
Data data = new Data();
Also, all the ArrayLists in the Data class should be outputted to a file which will be loaded next time the app is opened.
I will try to answer any questions.
You need to define a class which contain 3 data fields as follows
Name
Student ID
their points
But not to forget, the class has to have other necessary elements of a class like:
Constructor
Overloaded Constructors if they are necessary
Accessors
Mutators
Note: For accessing each part of an object in your arrayList, you can use accessors. For manipulating each part of an object in your arrayList, you can use mustators.
After having such a class, you can define a arrayList that contain elements with type of class you have already define
Like:
List<Your Type of class > students = new ArrayList<Your Type of class>;
After Java 7, you can do
List<Your Type of class > students = new ArrayList<>;
which is diamond inference.
If you are looking for a specific id number in your arrayList, you can do something like:
public boolean findIdNumber(int idNumber){
for(int i=0; i< students.size; i++)
if(students.get(i).getID() == idNumber)
return true;
else
return false;
}
Warning:
what I have done are suggestions for you to be able to look for what you want smoother. You need to do necessary changes in order to comply what you were
asked to do
You need to create a class named Student, and then declare an array/ArrayList of the Student type. Your Student class must have a constructor that sets the fields of an instance of the Student class (the created instance is now called an object).
So first create a Student class in the same package in which your other class is (the class in which your main method is):
public class Student {
private String firstName;
private String lastName;
private String studentId;
private int points;
public Student(String firstName, String lastName, String studentId, int points) {
this.firstName = firstName;
this.lastName = lastName;
this.studentId = studentId;
this.points = points;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
}
Then in your main method or wherever you like, create a Hashmap to hold your Student objects. A map/hashmap is a collection just like an ArrayList to hold a set of objects. In your use case, it is better to use a hashmap because finding/retrieving a specific student object is much faster and easier when you use a hashmap.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// a map is a "key-value" store which helps you search items quickly
// (by only one lookup)
// here you consider a unique value of each object as its 'key' in the map,
// and you store the whole object as the value for that key.
// that is why we defined Student as the second type in the following
// HashMap, it is the type of the "value" we are going to store
// in each entry of this map.
Map<String, Student> students = new HashMap<String, Student>();
Student john = new Student("John", "Doe", "401712", 20);
Student jack = new Student("Jack", "Young", "664611", 30);
students.put("401712", john);
students.put("664611", jack);
Student johnRetrieved = students.get("401712");
// each hashmap has a get() method that retrieves the object with this
// specific "key".
// The following line retrieves the student object with the key "664611".
Student jackRetrieved = students.get("664611");
// set/overwrite the points "field" of this specific student "object" to 40
johnRetrieved.setPoints(40);
int johnsPoints = johnRetrieved.getPoints();
// the value of johnsPoints "local variable" should now be 40
}
}
The classical object-oriented approach would be to create a Student class including name, ID and points and storing list of Student objects in a single ArrayList.
class Student{
private String id;
private String name;
private int points;
public Student(String id, String, name, int points){
this.id = id;
this.name = name;
this.points = points;
}
}
..
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student(1, 'John Doe', 1000));
String id = students.get(0).id;
I'm not too sure how to word this so it makes sense, but I'll try my best.
Say I have 2 classes. My main class, and a Person class.
My main class will create some Objects from the Person class like this
public class Example {
static Person bob = new Person(23);//Age
static Person fred = new Person(34);
static Person John = new Person(28);
//..and so on
public static void main(String args[]){
..
}
}
and in my Person class..
public class Person{
private int age;
public Person(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
}
Now, if I wanted the age of fred, I'd just call Fred.getAge();.
But, in my program, I don't know what person I'm getting the age of. It randomly selects one, and I need to get the name without directly calling the object. For example, I would have something like this in my Person class:
public static Object getPerson(){
//Some code to get a random integer value and store it it Var
switch(Var){
case 1:
return bob;
case 2:
return fred;
case 3:
return john;
}
}
What I would expect this to do is return an Object that I could then use like this:
public static void main(String args[]){
System.out.println(Person.getPerson().getAge());
}
What I thought that would have done was first call getPerson() which randomly returns either bob, fred, or john, and then it would call getAge(). So if getPerson() returned fred then it would be the same as doing fred.getAge();
Now, this doesnt work, and this was the only way I thought of that made sense to me.
How do I do this so it actually does what I want?
I'm very new to Java, and OOP, and this is my first time really working with different Objects. So I'm sorry if I'm using the wrong terms and explaining things weirdly.
Change
public static Object getPerson(){
to
public static Person getPerson(){
You can't call getAge on an Object, because the Object type does not have getAge() defined.
Why not put the name as a property of the Person class?
class Person {
// ... your existing code for age...
private String name;
String getName() { return name; }
// add name to constructor...
public Person(String name, int age) {
// set them up here...
}
}
The way I see it, is that name is for you as a human, but variables john are irrelivant to the program and computer.... you can even use p1 = Person("Joe", 42);
To get a person by age, you can use a Map with age as key, and person as value.
It could be the case that this is a misunderstanding, but how I'm interpreting the issue is as follows:
You need a (better) place to store all of your Person objects instead of having them as static variables.
You need a way to randomly select from wherever you're storing those objects.
Let's address the main issue first. You're creating these as static variables when they probably shouldn't be; they should just be created as entries into an array.
The way to do this is through this declaration:
Person[] people = new Person[] {new Person(23), new Person(34), new Person(28)};
The main issue now is that you have no way to refer to which person's age belongs to whom since you haven't attached a name field to any of these instances. You could do that easily:
public class Person {
private String name;
private String age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getters for name and age
}
...then you can instantiate your Person with two values.
new Person("Bob", 23);
Now that we've addressed one concern (which was where to store the people in the first place), now we need a way to randomly access them.
For that, we can use Random#nextInt().
Random rand = new Random();
System.out.println("Person's age - " + people[rand.nextInt(people.length)]);
This will randomly pull a Person out of the array and print their age.
If you want to get a random person within the person class you could store a reference to each person created, and then select randomly from that list
public class Person {
// A List of every Person Created.
private static final List<Person> allPeople = new ArrayList<People>();
// A source of random numbers
private static final Random rand = new Random();
...
public Person(int age) {
...
// Every time we create a new Person, store a reference to that person.
addPerson(this);
}
// synchronized as ArrayLists are not thread safe.
private static synchronized addPerson(Person person) {
allPeople.add(person);
}
...
public static Person getRandomPerson() {
// Get a random number between zero and the size of the list.
int random = rand.nextInt(allPeople.size() -1);
return allPeople.get(random);
}
Now this code is not what I would do in a production environment but it the question sounds like an exercise. A better way would be to store the people created in a List in your Example class. But trying to answer the question as you asked it.
OK, I have a bit of a conundrum. I'll say straight out that I'm working on a homework assignment and I've come to a stumbling point. I'm sure that I'm missing something obvious, but after hours of searching the internet and text books to try and find an answer to this, I'm butting up against a wall and I'm hoping someone can point me in the right direction.
I have created a class called "employee" that defines an employee object, it has getter and setter methods for the employee's name and sales totals. It looks as follows:
public class employee {
private String employeeName;
private double yearSales;
public employee(String employeeName, double yearSales)
{
this.employeeName = employeeName;
this.yearSales = yearSales;
}
public void setName(String employeeName)
{
this.employeeName=employeeName;
}
public void setSales(double yearSales)
{
this.yearSales=yearSales;
}
public String getEmployee()
{
return employeeName;
}
public double getYearsSales()
{
return yearSales;
}
}
I then have a method that is intended to instantiate an ArrayList that contains employee objects. I'm able to get as far as creating the ArrayList and adding information to it as shown below:
public ArrayList employeeArray(String name, double sales)
{
//Instantiate a new ArrayList object
ArrayList employeeList = new ArrayList();
//Initialize the values in the ArrayList
employeeList.add(new employee(name, sales));
return employeeList;
}
Where I am running into trouble is with attempting to print out the name value from the ArrayList, shown below:
System.out.println(employeeList.get(0).getEmployee());
I'm only adding one element so the index value should be correct, and I worked with ArrayLists in another Java course not too long ago and was able to do something similar to this in my code for those assignments. If I need to clarify anything more about this I'll be happy to. Of course, any assistance on this is greatly appreciated.
You should be using Generics if you have Java SE >= 5, so instead of ArrayList, use ArrayList<employee>. Otherwise, you'd need to cast its type from Object to Employee:
System.out.println(((employee)employeeList.get(0)).getEmployee());
Also, class and interface names in Java should start with an uppercase letter.
public ArrayList<employee> employeeArray(String name, double sales)
{
//Instantiate a new ArrayList object
ArrayList<employee> employeeList = new ArrayList<employee>();
//Initialize the values in the ArrayList
employeeList.add(new employee(name, sales));
return employeeList;
}
Youre trying to instantiate a new ArrayList with each call to employeeArray() method. Try maintaining a common ArrayList and add elements to it using this method.
Also +1 with using generics
And if you're new to Java, then do read this link as well: "Java Programming Style Guide (Naming Conventions)"
Assuming you've a class called EmployeeList where you have defined this method employeeArray(), you can update it to maintain new names in the list as follows (note that this is one sample solution, you are obviously welcome to tailor it to your need):
public class EmployeeList{
private ArrayList<Employee> employeeList;
public EmployeeList(){
//Initializing the employee arraylist
employeeList = new ArrayList<Employee>();
}
public ArrayList<Employee> employeeArray(String name, double sales){
//Initialize the values in the ArrayList
employeeList.add(new Employee(name, sales));
return employeeList;
}
}
Also note the use of generics and the naming conventions in the above code. This might be helpful for you.