Prevent object stored in ArrayList from being over written - java

Basically I have to write a simple contact manager, and store objects in array list.
What frustrates me is that I have newContact method, which when called creates new instance of Contact, and stores it in ArrayList. The problem is that every time I call that method, all other objets in the list gets overwritten.
import java.util.ArrayList;
public class ContactManager {
public static ArrayList<Contact> contactList = new ArrayList<Contact>();
public static Contact[]c = {};
public static void main(String[]args){
newContact();
newContact();
System.out.println(contactList.get(1).getName());
System.out.println(contactList.get(0).getName());
}
public static void newContact(){
Contact c = new Contact();
contactList.add(c);
}
}
In Contact class constructore there is code that initializes the object's properties using Scanner class.
If in first call I Enter "John" and in second function call I enter "Peter", the above code will print out:
Peter
Peter.
Why doesn't it prints out John Peter?
Only thing I can think of is that maybe Java stores only reference to object in arraylist, and that unlike variables objects don't get destroyed after function executes..
Any ways around this?
I hope this explains what I am trying to achieve.
PS. I know people hate people that as homework questions. But I am doing this as an extra, in order to learn new stuff. Original assignment barely asks to instantiate 5 objects and store them in ArrayList. And I have that done, now I am just trying to see if I could come up with more dynamic solution.
Contact class code:
import java.util.Scanner;
public class Contact{
private static String name, number;
//constructor will ask to enter contact details
public Contact(){
Scanner in = new Scanner(System.in);
System.out.println("Enter name:");
name = in.next();
System.out.println("Enter number:");
number = in.next();
}
//getters and setters
public static String getName(){
return name;
}
public static String getNumber(){
return number;
}
public static void setName(String newName){
name = newName;
}
public static void setNumber(String newNumber){
number = newNumber;
}
}

It's because the members in the Contact class are static. That means that all Contact instances share the same name and number. You should make them instance members so that each time you do new Contact you get a new copy of these variables.

Related

Creating new objects and initialising them

The assignment question was define a Constructor for class player, it asks to input the players name (which I think I've done correctly), and initialise the position to zero as well to create a players jar by using new Jar();
So I created 2 classes one called Jar and one called Player, basically a players Jar Position is meant to be 0 and a players Stone is meant to be null. (Player position and Jar position are different)
public class Jar
{
public static int position;
public static Jar stone;
/**
* Constructor for objects of class Jar
*/
public Jar()
{
this.position = 0;
this.stone = null;
}
}
import java.util.Scanner;
public class Player
{
// instance variables - replace the example below with your own
private String name ;
private int position;
private Player JarPosition;
private Player JarStone;
/**
* Constructor for objects of class Player
*/
public Player()
{
System.out.print("Enter player's name: ");
name = Global.keyboard.nextLine();
this.position = 0;
Jar jar = new Jar();
JarPosition = jar.position;
JarStone = jar.stone;
lets go through it step by step.
First you start your program with a main method:
public static void main(String[] args){
// execute this code here
}
This method you can put in any class you like, though I would suggest to put it in a class that you will use to "control" your program's flow:
public class MyJarProgram{
public static void main(String[] args){
}
}
Now to get rid of all that static and non-static confusion, let's keep with "Objects" (instances of classes). Meaning this main method is the only static thing you will need.
Now you want to start constructing your players, the jar (I don't really know what that is but nevermind :) and positions and everything, so you might want to start asking the user for the players name:
public static void main(String[] args){
System.out.print("Please enter the player's name");
String playerName = Global.keyboard.nextLine(); // I guess this method works like this, so your variable playerName should now contain the user's input
// now you can instantiate your player object
Player player = new Player(playerName); // here we need a constructor of the class player that takes the name.
}
So now you have to create your Player class and give it the constructor with the name
public class Player{
private String name; // make all variables in your classes non-static and private to be on the save-side
public Player(String name){
this.name = name; // you take the parameter name and set the private member variable name to the same value
}
// since your variable name is private to the class player you might want to add some standard getter and setter methods like this:
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
As you did it with the name of the player, you could do it with the position as well. Give the Player class another member variable position and add the necessary code to the constructor (and maybe the getter and setters too).
Then your main method could look like this:
public static void main(String[] args){
System.out.print("Please enter the player's name");
String playerName = Global.keyboard.nextLine();
Player player = new Player(playerName, 0); // creates the player with his name and position.
System.out.println("Player :"+player.getName()+" is on position "+player.getPosition()); // and that's how you can access the players attributes with your getters and setters
}
Although I guess you might want to give the player by default position 0, in which case you don't pass the position in the constructor but set the position to 0:
public Player(String name){
this.name = name; // takes the parameter to init the name
this.position = 0; // will initialize the position by default with 0
}
Well I hope this helps you get a better idea on constructors and classes and stuff. Good luck!

Setting object value with method in main class?

I am trying to set specific values of objects in an Array with a method.
public class BankAccount
{
private String name;
//constructor
public BankAccount(String firstName, String LastName)
{
name = firstName + " " + lastName;
}
public String getName()
{
return name;
}
Above is my BankAccount class, and I have another class named BankAccountList:
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = giveName("MR", "Travis");
}
public static void giveName (String firstName, lastName){
}
}
How do I set the object name in BankAccount[1] to "Mr Travis" with the following giveName() method? I don't know what to put in giveName with the given parameter. Any tips would be much appreciated.
Your giveName method should return the type BankAccount:
public static BankAccount giveName (String firstName, String lastName){
return new BankAccount(firstName, lastName);
}
Edit:
Simply declaring new BankAccount[] does not populate any entries in the array (which you might expect based on experiences with other languages). The array will initially be empty, and there are multiple ways to populate it:
Inside a loop you could:
Call the BankAccount constructor directly
Delegate to another method that returns a new .collect(Collectors.toSet()) (as the example above does)
This choice, like most programming decisions, is mostly personal preference. For a simple DTO with 2 string fields, delegating to another method might be overkill.
For a more complex DTO that requires validation, delegating to another method helps encapsulate that validation logic in a single place that is easily testable.
There are a few things worth mentioning here.
First of all, it seems like you do not have a complete understanding of the difference between static and dynamic. It is understandable, as I even now would have a hard time explaining it easily, even though I understand how it works. Your BankAccountList class has a main method, started from a static standard main method. your bankAccount array is defined within this main method, meaning it does not exist in the whole class, only inside the running main method.
Then you want to give name to a bank account in the list. Here you have created another static method, which knows nothing about what is inside your main method, and it does not contain any object which the parameters can be given to. In other words the empty function you have now, can't set any parameters to a bank account, because no bank account exists within the method.
I would recommend making the giveName method dynamic (which means just removing the static keyword), and move the method to the BankAccount class. Then you will efficiently have both a get and set method for name, which are dynamic, meaning it is valid per object instance of the class. After that, it is possible to first refer to an object in the array, and directly call the giveName() method on that particular object, which will set the name:
public class BankAccount
{
private String name;
//constructor
public BankAccount(String firstName, String LastName)
{
name = firstName + " " + lastName;
}
public String getName()
{
return name;
}
public void giveName (String firstName, String lastName){
name = firstName + " " + lastName;
}
and:
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1].giveName("MR", "Travis");
}
}
UPDATE:
I noticed now another thing. The line where you create the array:
BankAccount bankAccount[] = new BankAccount[2];
This does not create a populated array, it creates an empty array. in other words, you have not created a list with bank accounts, you have created a list which can hold bank accounts. You will have to create a bank account first, before being able to give it a name.
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = new BankAccount("MR", "Travis");
Now, your constructor already has parameters for giving an account a name, when created. So now you don't really need the giveName method. Unless you want to change it later:
bankAccount[1].giveName("MRS", "Davis");
You don't really need to use giveName method, you could just do it like this:
bankAccount[1] = new BankAccount("MR", "Travis");
But, if you really need to do it using a giveName method, you could do it like this:
// change signature to return `BankAccount` object
public static BankAccount giveName (String firstName, String lastName){
return new BankAccount(firstName, lastName);
}
and call it like this: bankAccount[1] = giveName("MR", "Travis");
If you need giveName to have void as return type, then you need to pass the array in order to add the BankAccount inside the method and the position were it will be added. Like this:
// change in order to signature receive an array of `BankAccount`s and the position where it will be added
public static void giveName (String firstName, String lastName, BankAccount[] bankAccounts, int position) {
bankAccounts[position] = new BankAccount(firstName, lastName);
}
and then call it like this: giveName("MR", "Travis", bankAccount, 1);
Additional notes:
Remember array positions start at index 0, not 1, so you might want to consider adding bank account from 0, not 1, like this:
This is the case if giveName is in the BankAccountList class. Otherwise, go for KjetilNordin's answer.
bankAccount[0] = giveName("MR", "Travis");
You defined an array that will hold BankAccount objects, so to add elements into it with the function giveName() you need to modify that function as following :
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = giveName("MR", "Travis");
}
public static BankAccount giveName (String p_firstName,String p_lastName){
return new BankAccount(p_firstName, p_lastName)
}
}
You need set methods!
Add this to class BankAccount:
public void setName(String firstName, String lastName) {
this.name = firstName + " " + lastName;
}
so you should call setName instead of giveName. Like this:
bankAccount[1].setName(String firstName, String lastName)
Another thing, I suggest you use the set method in the constructor of your object:
//constructor
public BankAccount(String firstName, String LastName)
{
setName(String firstName, String lastName);
}

Best approach for designing a Java class? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I hope I am asking the right question. This is just out of my curiosity and since I am not an experienced developer, I just to wanted to hear from you guys that what is the good approach while designing a class. Is there any standard approach or either one can be implemented? I just to want to know what is the conventional way of creating a class or what is your way?
Option 1:
public class Student{
private String name;
private String address;
public Student(String name, String address){
this.name = name;
this.address = address;
}
public void addStudent(){
//add name and address to database.
}
}
Option 2:
public class Student{
public void addStudent(String name, String address){
//add name and address to database.
}
public void addAllStudent(List Student){
//loop and add each student to database
}
}
Method call:
//option 1:
Student s = new Student("abc","xyz");
s.addStudent();
//for list,
for(int i=0;i<list.length;i++){
Student s = new Student(list[i].name, list[i].address);
s.addStudent();
}
//option 2:
Student s = new Student();
s.addStudent("abc","xyz");
s.addAllStudent(list);
Option 2 is not good, since both methods dont really have anything to do with the Student object they belong to. You could make those two methods static. Option 1 is the "right" way for a Student class, but the method addStudent() is wrong. You can have a method in your database and call database.addStudent(objStudent).
You could also change the addStudent method in your Student class to addToDatabase(Database db) or even
static void addToDatabase(Student student, Database db)
In the specific case of a List as Database, there is no need for a custom add method at all, because List allready has the add method.
In the most simple case it all boils down to:
List<Student> students = new ArrayList<Student>();
students.add(new Student("Max", "###"));
If you think the second line is too complicated, you can create a static method in Student:
public static void addStudent(String name, String address, List<Student> students)
{
students.add(new Student(name, address);
}
Then you can use it like this:
List<Student> students = new ArrayList<Student>();
Student.addStudent("Max", "###", students);
From personal preference i would not do the latter. It bugs me a little that its not transparent enough in terms of what the method actually does with the list. There is nothing wrong with simply using the add method of the list in the first case.
As you can see there are a lot of opinions on this question, so I go and add another one ;)
Someone commented that there is no "silver bullet" to use when creating new instances of a class. That pretty much hits the bull's eye. There are many ways, straight forward via a constructor, via static methods or wrapped in Factories. And there are even very good arguments to create an instance via reflections.
The same is true for how to save your students to the database. There are many patterns that may be valid. Just make sure you understand how that pattern works and what are the benefits and disadvantages. And just as important, use it consequently throughout your code.
Regarding your code, your option 2 does not make sense if you change to a modeling perspective. Adding students to a student? Unless you don't want to create a human pile of students, you better add students to a course, a class, a school...
Well... first things first... there is a difference between the a Studentand a List<Student>
Normally you would create a class Student
public class Student{
private String name;
private String address;
public Student(String name, String address){
this.name = name;
this.address = address;
}
// and some getter
}
and somewhere else in your code you can use a java List (not in your Student-Class)
List<Student> students = new ArrayList<Student>();
Student peter = new Student("Peter", "somewhere");
Student frank = new Student("Frank", "somewhere else");
students.add(peter);
students.add(frank);
This Code snipped could be in your SubscribeStudentToCourseService or so...
What you want to do is - SingleResponsibility:
Create a class which is responsible for only one thing:
a StudentClass which represents the student as a java model
a course which represents a course (perhaps with a List<Student> field for the students who visit the course
perhaps you write a Service To subscribe Students to a course
It seems you are using the same class to provide a template for a Student, and also to store Students.
Do you really need to store students in the same class? It will lead to some confusing design, where you've got a Student class storing other Student classes which actually represent a student.
Perhaps the functionality for adding a student could be in a separate class, such as a School? Or you just create a generic List of Students wherever you need them. So the addStudent functions could possibly be removed from the class and stored elsewhere.
You can try something like this:
Create a Student bean
public class Student {
private String name;
private String address;
public Student(String name, String address) {
this.name = name;
this.address = address;
}
// generate the getters and setters
}
Create the DAO class
public class StudentDaoIml {
public void addStudent(Student student) {
// do the add student job here
}
public void addAll(List<Student> students) {
// the code goes here
}
public void deleteStudent(Student student) {
}
...
}
At the end you can use it like this:
StudentDaoIml stDao = new StudentDaoIml();
for(int i=0;i<someValue; i++){
Student s = new Student(list[i].name, list[i].address);
stDao.addStudent(s);
}
Here's a good way and some explanation in comments.
public class Student{
private String name;
private String address;
public Student(String name, String address){
this.name = name;
this.address = address;
}
public void save(){
//save this instance to database.
}
public static void saveAll(List<Student> students){
//Either iterate and call save
// or do better batch insert for better performance
}
}
As far as naming a method is concerned, class methods are named in terms of their behaviour. Think of it like telling an instance of student to 'go and save yourself to DB'. There could be one more method like 'go and update yourself in DB'.
When you are dealing with a list, the list itself should not be part of the Student class. Keep the list somewhere else. However, the Student class could have a static method which takes a list of students and saves them in one shot.
For example, the students could be in a class in a school. Then
Student.saveAll(class5A.getStudents());
Create a few and save them:
List<Student> students = new ArrayList<>();
for(int i=0;i<10;i++){
Student s = new Student("Student" + i, "Student address " + i);
students.add(s);
}
Student.saveAll(students);
Going one step further, Student class should probably not deal with saving students in bulk. So, let's relieve it of that duty and let the BatchOfClass take care of that.
public class Student{
private String name;
private String address;
public Student(String name, String address){
this.name = name;
this.address = address;
}
public void save(){
//save this instance to database.
}
}
public class BatchOfClass{ //Students who are in grade 6 in 2016
private String className;
private String batchName;
private List<Student> students;
public BatchOfClass(...){
}
public void save(boolean saveStudents){
//save this instance to database.
//This would also save the students to DB if saveStudents==true
}
}

Why Object "Adult" cannot be printed out?

package com.java.zha;
public class Person{
private String name;
public Person(){
}
public Person(String name1){
this.name=name1;
}
public void printkk(){
for (int i=0; i<3;i++){
System.out.println(Adult[i].name);/*the prompt message said that" the Adult can not be resolved as an variant.*/
}
}
public static void main(String[] args){
Person[] Adult= new Person[3];
Adult[0]=new Person("zhangbin");
Adult[1]=new Person("zhangchangqing");
Adult[2]=new Person("nana");
System.out.println(Adult[2].name);
Adult[1].printkk();
}
}
PS: I created an object Adult and a printkk() method which used to print all the member's name of the Adult array. But it give me an error. So I ask help from your guys. I am just starting to code please answer it in detail. thanks in advance!
You're trying to access private fields, change private String name; to public String name; or add a getName() method so that you can print out the name with System.out.println(Adult[2].name); or System.out.println(Adult[2].getName();.
Your printkk() method is trying to print out a non-existant Adult array. You'll need to pass it as an argument to the method, so change public void printkk() to public void printkk(Person[] Adult) and then change Adult[1].printkk(); to Adult[1].printkk(Adult);
This is probably the easiest way to get your code to work, but it would be better to scrap what you have and rewrite most of it.

Can I make new methods dynamicly in a loop or in an other matter

In school we have to make a program, which is that you type in personal information, such as namn, age and so on. And you have one button where you save information and one where you type out.
I save this information like this:
Person.name = Name.getText();
Person.age = age.getText();
Person.sex = sex.getText();
And then i have a method. Which takes this information and saves it. Because there is only one button to save information. Can you make new mothods for every new person you save? Should you do it in a loop. That loops out new methods everytime you press? And how.
Thx
You do not need to 'make new methods' each time you want to save the Person data. The point is to create a method which is dynamic, that means you have to have access to the Person class/data and just do as you defined: person.setName(name.getText());
You dont need a new method everytime you save, you need a new Person object. The method that gets called when save is pressed should accept Person as a parameter. So save is pressed it creates a new Person object and populates it like u already do, Person.name = Name.getText();, Person.age = age.getText(); and so on. That populated Person object is then passed to a method which has all the code to save it.
You do not need to make new method every time, what you need to do is just make a class named Person and define its attributes as Name, Age and Sex and make methods that access this variables and sets this variables, as I've shown below:
class Person{
String Name="";
String Age="";
String Sex="";
public String getName(){
return Name;
}
public String setName(String Name){
this.Name=Name;
}
public String getAge(){
return Age;
}
public String setAge(String Age){
this.Age=Age;
}
public String getSex(){
return Name;
}
public String setName(String Sex){
this.Sex=Sex;
}
}
You can access this methods and variables by just making object of this Person class as:
Class UsePerson{
public static void main(String ar[]){
Person p=new Person();
p.setName("ABC"); //Here You set the Name of the person
String name=p.getName(); //Here you'll get the name of Person
}
}

Categories

Resources