Objects share same values, even when "new" is used - java

I'm trying to do something pretty simple but I can't seem to get it to work. I'm trying to iterate through an ArrayList but my for loop is always returning the same value when I output the results to the terminal.
Here is the code:
import java.util.*;
public class Contact{
public static ArrayList<Contact> contacts = new ArrayList<Contact>();
public static String name;
public static String phoneNumber;
public static String email;
private static int idCounter = 0;
private final int contactID;
public static void main(String[] args){
Contact bob = new Contact("bob","8493483943","jo#g.com");
Contact joe = new Contact("joe","940389439","something#g.com");
ArrayList<Contact> contacts = new ArrayList<Contact>();
contacts.add(bob);
contacts.add(joe);
for (Contact person : contacts) {
System.out.println(person.idCounter);
System.out.println(person.name);
System.out.println(person.phoneNumber);
System.out.println(person.email);
System.out.println();
}
}
public Contact(String name,String phoneNumber,String email){
this.contactID = idCounter++;
this.name = name;
this.phoneNumber = phoneNumber;
this.email = email;
}
}
The above code always returns this when I run the code:
2
joe
940389439
something#g.com
2
joe
940389439
something#g.com
It returns the same information even though I've added 2 different objects into the ArrayList.
When I do this inside the for loop:
System.out.println(person);
It returns a Contact object with different id's.
I'm a little confused as to why this is happening as I'm assuming I'm not referencing the same variable or object here, or that I'm doing something wrong in my loop.
If anyone could help me explain what's going on that'd be great, thanks!

your attributes are static: name, phoneNumber and email. Remove static keyword [static keyword make classlevel attributes] :)

All your class variables are static. This means they will be overwritten ones you create the second object.

Related

How to change array to an object class?

I have cut out the code to shorten the page but I'm asking how do I change personInterests into its own class. Apologies for the vague question but essentially I want to change personInterests in my Person class to a class where personInterests has multiple variables.
import java.util.ArrayList;
import java.util.*;
public class Person{
private String personName;
private String[] personInterests = new String[3];
public Person(String personName, String[] personInterests){
this.personName = personName;
this.personInterests = personInterests;
}
public void setInterests(String[] personInterests){
this.personInterests = personInterests;
}
public String[] getInterests(){
return personInterests;
}
public String getName(){
return personName;
}
public String toString(){
String result = getName() + " ";
for (String interests : personInterests) {
result += interests + " ";
}
return result;
}
}
This was my idea of how it would work just not sure how I would use this class and call it later on.
import java.util.ArrayList;
import java.util.*;
public class Interests {
private int interestDangerRating;
private String interestName;
private ArrayList<Interests> interestsList = new ArrayList<>();
public Interests (int interestDangerRating ,String interestName){
this.interestDangerRating = interestDangerRating;
this.interestName = interestName;
}
public void addInterests(Interests p){
interestsList.add(p);
}
Interests getInterests(int i){
return interestsList.get(i);
}
}
Any help is appreciated, as I said this code has mostly been taken out and this was an old project already completed just wanted to see if I could change some of the features.
OK so here's what I would do to clean this up for you and make it work. Firstly, think about what you are trying to do. You want to create a Person who has multiple Interests, right? So the Interest class, going by your above example, can be changed to be a typical Java object class as follows:
public class Interest {
private int dangerRating;
private String name;
public Interest (int dangerRating, String name) {
this.dangerRating = dangerRating;
this.name = name;
}
public int getDangerRating() {
return dangerRating;
}
public String getName() {
return name;
}
}
So now we've an Interest class set up where you can set a name for your interest and a danger rating. What we need to do, now, is edit your Person class so as you can store a list of interests for each Person you create.
import java.util.ArrayList;
public class Person{
private String name;
private ArrayList<Interest> interests = new ArrayList<Interest>();
public Person(String name, ArrayList<Interest> interests) {
this.name = name;
this.interests = interests;
}
public void addInterest(Interest newInterest) {
interests.add(newInterest);
}
public Interest getInterest(int indexOfInterest) {
return interests.get(indexOfInterest);
}
public ArrayList<Interest> getInterests() {
return interests;
}
public String getName() {
return name;
}
public String toString() {
String result = getName() + " ";
for(Interest interest : interests) {
result += interest.getName() + "(" + interest.getDangerRating() + ")" + " ";
}
return result.trim();
}
}
This allows you to set an initial list of all interests for your new Person and, from there, you can add new interests, get all interests or get any individual interest.
Hope this helps to clarify for you how this should all fit together!
So now it's time to instantiate everything. Lets create some Interestobjects which we will use:
Interest golf = new Interest(1, "golf");
Interest swimming = new Interest(3, "swimming");
Now lets assume we want two people called John and Mary. John likes golf and swimming while Mary only likes swimming. We'd then create their list of Interest as follows:
ArrayList<Interest> johnsInterests = new ArrayList<Interest>();
johnsInterests.add(golf);
johnsInterests.add(swimming);
ArrayList<Interest> marysInterests = new ArrayList<Interest>();
marysInterests.add(swimming);
And finally, we'd then create our two Person objects which will include the persons name and interests list.
Person john = new Person("John", johnsInterests);
Person mary = new Person("Mary", marysInterests);
And voila!
First, make an Interestclass:
public class Interest {
private int interestDangerRating;
private String interestName;
// .. getters and setters
}
then in the Personclass get rid of private String[] personInterests = new String[3];
and replace it by:
private ArrayList<Interest> interestsList = new ArrayList<>();
You're getting there with the logic of your Interests class, but it needs a few changes
import java.util.ArrayList;
import java.util.*;
public class Interests {
private int interestDangerRating;
// Is this a unique name for the entire class? If yes then no worries, but if not
// then its not needed, you've already got a list of interest names below
private String interestName;
// Change the array list to hold Strings, it's a list of words
private ArrayList<String> interestsList = new ArrayList<>();
public Interests (int interestDangerRating ,String interestName){
this.interestDangerRating = interestDangerRating;
this.interestName = interestName;
}
public void addInterest(String p){ // Again, change this to String
interestsList.add(p);
}
String getInterest(int i){ // Change this to return a String, since we changed the ArrayList above
return interestsList.get(i);
}
}
There's alot more you need to think about with this class too. How do you know how many interests are in the list, should there be a length variable? Or what about a method that returns the entire list of interests rather than just 1?
Also, there's only one interestDangerRating being set in this class; if each interest has a different danger rating, should't you be adding a danger rating for every interest?
In terms of accessing your new class, you'll need to create a class in your code by:
Interests variableName = new Interests(1, "football");
I have randomly chosen '1' and 'football' above, since they are in your Interest class' constructor. The way your class is built, you cannot use it without providing an int and a String when the object is made
Finally, to call methods on your class, you use the variable created above to call its methods:
variableName.addInterest("basketball");
String interest = variableName.getInterest(1);
If you're struggling, I recommend looking at a simple java tutorial online. instatiating java classes and calling their methods like this are fundamental concepts in Java :)

Java, How do i use add a string and an integer to an array

This is the array code I have so far:
ArrayList<Data> arrl = new ArrayList<Data>();
arrl.add("Tim", 23);
Need to know how to an integer and a string to the array.
For Example:
names: and ages:
Tim 23
Max 56
Clare 43
I know how to add integers OR strings to array-lists but i can't figure how to incorporate both in the same array.
Your list is taking objects of type Data. So, create a Data class that contains a String for the name and int for the age. Create a Data object for each entry you want and add it to your arrl list.
public class Data {
private String name;
private int age;
/**
* Constructor
*/
public Data(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and Setters go here.
}
In this example I used a constructor to allow easy construction of a Data object with a name and age.
List<Data> arrl = new ArrayList<Data>();
arrl.add(new Data("Tim", 23));
You could have a class Person for instance, where you save the name and age of a person.
Then, you have a ArrayList of Person, and you can store and access that information.
ArrayList is a class that use generics, it means type-safety, so when you declare a class that use generic in its class definition you have to declare the type when making the instance.
If you want to store Stringobjects declare ArrayList in this way:
ArrayList<String> saveString = new ArrayList<String>
You can make a class Person with those instance variables and resolve your problem.
For example:
public class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
And then you can use in this way:
ArrayList<Person> people = new ArrayList<Person>();
people.add(new Person("Luis Alberto",15));
Your arraylist is made for Data objects that means you have to create Data object to put it there, `this is what i mean by that arrl.add(new Data("Tim",44));
Make sure that you have class Data with constructor for string and int
Something like this:
public class Main {
public static void main(String[] args) {
ArrayList<Person> arrl = new ArrayList<>();
arrl.add(new Person("Tim", 23));
}
}
class Person {
private String name;
private int age;
Person (String name, int age) {
this.name = name;
this.age = age;
}
}
I think the best approach is what is proposed by Wabs and Ashot Karakhanyan. But if your need, is to have the name and age as different items of your list, you can use the following:
List<Object> arrl = new ArrayList<Object>();
arrl.add("name");
arrl.add(23);

String Array object in Java

I am trying to print the first element on the two arrays in my Athlete class, country and name. I also need to create a object that simulates three dive attemps an athlete had (that is initially set to zero). I am new to OOP and I dont know how to go abouts doing this in my main... as far as constructors go. This is what i have done so far...
this is the main:
import java.util.Random;
import java.util.List;
public class Assignment1 {
public static void main(String[] args) {
Athlete art = new Athlete(name[0], country[0], performance[0]);
}
}
I just really am not sure what to do...
And this is the class with the arrays.
import java.util.Random;
import java.util.List;
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
//Here i would like to create something that would be representing 3 dive attemps (that relate to dive and score. eventually.)
Athlete(String[] name, String[] country, Performance[] performance) {
this.name = name;
this.country=country;
this.performance=performance;
}
public Performance Perform(Dive dive){
dive.getDiveName();
return null;
}
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
public String[] getCountry() {
return country;
}
public void setCountry(String[] country) {
this.country = country;
}
}
thanks in advance for any help and input!
btw there is other classes too, just not relevant atm..
First, as for your Athlete class, you can remove your Getter and Setter methods since you have declared your instance variables with an access modifier of public. You can access the variables via <ClassName>.<variableName>.
However, if you really want to use that Getter and Setter, change the public modifier to private instead.
Second, for the constructor, you're trying to do a simple technique called shadowing. Shadowing is when you have a method having a parameter with the same name as the declared variable. This is an example of shadowing:
----------Shadowing sample----------
You have the following class:
public String name;
public Person(String name){
this.name = name; // This is Shadowing
}
In your main method for example, you instantiate the Person class as follow:
Person person = new Person("theolc");
Variable name will be equal to "theolc".
----------End of shadowing----------
Let's go back to your question, if you just want to print the first element with your current code, you may remove the Getter and Setter. Remove your parameters on your constructor.
public class Athlete {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germany", "USA"};
public Athlete() {
}
In your main method, you could do this.
public static void main(String[] args) {
Athlete art = new Athlete();
System.out.println(art.name[0]);
System.out.println(art.country[0]);
}
}
Currently you can't access the arrays named name and country, because they are member variables of your Athelete class.
Based on what it looks like you're trying to do, this will not work.
These arrays belong in your main class.
Your attempt at an athlete class seems to be dealing with a group of athletes, which is a design fault.
Define a class to represent a single athlete, with fields that represent the athlete's attributes:
public class Athlete {
private final String name;
private final String country;
private List<Performance> performances = new ArrayList<Performance>();
// other fields as required
public Athlete (String name, String country) {
this.name = name;
this.country = country;
}
// getters omitted
public List<Performance> getPerformances() {
return performances;
}
public Performance perform(Dive dive) {
// not sure what your intention is here, but something like this:
Performance p = new Performance(dive, this);
// add new performance to list
performances.add(p);
return p;
}
}
Then your main method would use ti like this:
public class Assignment1 {
public static void main(String[] args) {
String[] name = {"Art", "Dan", "Jen"};
String[] country = {"Canada", "Germant", "USA"};
Dive[] dive = new Dive[]{new Dive("somersault"), new Dive("foo"), new Dive("bar")};
for (int i = 0; i < name.length; i++) {
Athlete athlete = new Athlete(name[i], country[i]);
Performance performance = athlete.perform(dive[i]);
// do something with athlete and/or performance
}
}
}
I think you are a little messed up with what you doing.
Athlete is an object, athlete has a name, i has a city where he lives.
Athlete can dive.
public class Athlete {
private String name;
private String city;
public Athlete (String name, String city){
this.name = name;
this.city = city;
}
--create method dive, (i am not sure what exactly i has to do)
public void dive (){}
}
public class Main{
public static void main (String [] args){
String name = in.next(); //enter name from keyboad
String city = in.next(); //enter city form keybord
--create a new object athlete and pass paramenters name and city into the object
Athlete a = new Athlete (name, city);
}
}
public static void main(String[] args) {
public String[] name = {"Art", "Dan", "Jen"};
public String[] country = {"Canada", "Germant", "USA"};
// initialize your performance array here too.
//Your constructor takes arrays as an argument so you need to be sure to pass in the arrays and not just objects.
Athlete art = new Athlete(name, country, performance);
}
First off, the arrays are pointless, let's get rid of them: all they are doing is providing values for mock data. How you construct mock objects has been debated ad nauseum, but clearly, the code to create the fake Athletes should be inside of a unit test. I would use Joshua Bloch's static builder for the Athlete class, but you only have two attributes right now, so just pass those in a Constructor. Would look like this:
class Athlete {
private String name;
private String country;
private List<Dive> dives;
public Athlete(String name, String country){
this.name = name;
this.country = country;
}
public String getName(){
return this.name;
}
public String getCountry(){
return this.country;
}
public String getDives(){
return this.dives;
}
public void addDive(Dive dive){
this.dives.add(dive);
}
}
Then for the Dive class:
class Dive {
private Athlete athlete;
private Date date;
private double score;
public Dive(Athlete athlete, double score){
this.athlete = athlete;
this.score = score;
this.date = new Date();
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
public Athlete getAthlete(){
return this.athlete;
}
}
Then make a unit test and just construct the classes, and manipulate them, make sure that they are working. Right now they don't do anything so all you could do is assert that they are retaining the Dives that you are putting in them. Example:
#Test
public void testThatDivesRetainInformation(){
Athlete art = new Athlete("Art", "Canada");
Dive art1 = new Dive(art, 8.5);
Dive art2 = new Dive(art, 8.0);
Dive art3 = new Dive(art, 8.8);
Dive art4 = new Dive(art, 9.2);
assertThat(art.getDives().size(), is(5));
}
Then you could go through and add tests for things like, making sure that you can't construct a dive without an athlete, etc.
You could move construction of the athletes into the setup method of the test so you could use it all over the place. Most IDEs have support for doing that with a refactoring.

ArrayList - How to modify a member of an object?

I have a number of Customer objects stored in an ArrayList. My Customer class has 2 data members: Name and Email. Now I want to modify just the Email for Customer "Doe".
Now if "Doe" is located at index 3 in the list, I know I can write this line:
myList.set( 3, new Customer( "Doe", "j.doe#supermail.com" ) );
But that means creating a new object. If I have a very big list, I suppose the process would be very slow. Is there any other way to directly access the data member of an Object stored in an ArrayList, maybe by using another kind of Collection than ArrayList?
You can do this:
myList.get(3).setEmail("new email");
Fixed. I was wrong: this only applies on element reassignment. I thought that the returned object wasn't referencing the new one.
It can be done.
Q: Why?
A: The get() method returns an object referencing the original one.
So, if you write myArrayList.get(15).itsVariable = 7or myArrayList.get(15).myMethod("My Value"),you are actually assigning a value / using a method from the object referenced by the returned one (this means, the change is applied to the original object)
The only thing you can't do is myArrayList.get(15) = myNewElement. To do this you have to use list.set() method.
You can iterate through arraylist to identify the index and eventually the object which you need to modify. You can use for-each for the same as below:
for(Customer customer : myList) {
if(customer!=null && "Doe".equals(customer.getName())) {
customer.setEmail("abc#xyz.com");
break;
}
}
Here customer is a reference to the object present in Arraylist, If you change any property of this customer reference, these changes will reflect in your object stored in Arraylist.
Assuming Customer has a setter for email - myList.get(3).setEmail("j.doe#supermail.com")
I wrote you 2 classes to show you how it's done; Main and Customer. If you run the Main class you see what's going on:
import java.util.*;
public class Customer {
private String name;
private String email;
public Customer(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return name + " | " + email;
}
public static String toString(Collection<Customer> customers) {
String s = "";
for(Customer customer : customers) {
s += customer + "\n";
}
return s;
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("Bert", "bert#gmail.com"));
customers.add(new Customer("Ernie", "ernie#gmail.com"));
System.out.println("customers before email change - start");
System.out.println(Customer.toString(customers));
System.out.println("end");
customers.get(1).setEmail("new.email#gmail.com");
System.out.println("customers after email change - start");
System.out.println(Customer.toString(customers));
System.out.println("end");
}
}
to get this running, make 2 classes, Main and Customer and copy paste the contents from both classes to the correct class; then run the Main class.
Use myList.get(3) to get access to the current object and modify it, assuming instances of Customer have a way to be modified.
You can just do a get on the collection then just modify the attributes of the customer you just did a 'get' on. There is no need to modify the collection nor is there a need to create a new customer:
int currentCustomer = 3;
// get the customer at 3
Customer c = list.get(currentCustomer);
// change his email
c.setEmail("somethingelse#example.com");
Well u have used Pojo Entity so u can do this.
u need to get object of that and have to set data.
myList.get(3).setEmail("email");
that way u can do that. or u can set other param too.
If you need fast lookup (basically constant time) of a object stored in your collection you should use Map instead of List.
If you need fast iteration of the objects you should use List.
So in your case...
Map<String,Customer> customers = new HashMap<String,Customer>();
//somewhere in the code you fill up the Map, assuming customer names are unique
customers.put(customer.getName(), customer)
// at some later point you retrieve it like this;
// this is fast, given a good hash
// been calculated for the "keys" in your map, in this case the keys are unique
// String objects so the default hash algorithm should be fine
Customer theCustomerYouLookFor = customers.get("Doe");
// modify it
theCustomerYouLookFor.setEmail("newEmail#stackoverflow.com")
Without function here it is...it works fine with listArrays filled with Objects
example
`
al.add(new Student(101,"Jack",23,'C'));//adding Student class object
al.add(new Student(102,"Evan",21,'A'));
al.add(new Student(103,"Berton",25,'B'));
al.add(0, new Student(104,"Brian",20,'D'));
al.add(0, new Student(105,"Lance",24,'D'));
for(int i = 101; i< 101+al.size(); i++) {
al.get(i-101).rollno = i;//rollno is 101, 102 , 103, ....
}
Any method you use, there will always be a loop like in removeAll() and set().
So, I solved my problem like this:
for (int i = 0; i < myList.size(); i++) {
if (myList.get(i).getName().equals(varName)) {
myList.get(i).setEmail(varEmail);
break;
}
}
Where varName = "Doe" and varEmail = "j.doe#supermail.com".
I hope this help you.
Try this.This works while traversing the code and modifying the fields at once of all the elements of Arraylist.
public Employee(String name,String email){
this.name=name;
this.email=email;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
for(int i=0;i++){
List.get(i).setName("Anonymous");
List.get(i).setEmail("xyz#abc.com");
}

Contact list program

My assignment is to create a basic contact list program that lets the user
Enter a new contact,
Print the contact list,
Retrieve a contact by last name,
Email, and
Retrieve contacts in a specific zip code.
My idea is to create 3 classes:
Main(), Contact(), and ContactList(). I would proceed by having the main() handle the menu and the logic. Contact() would be a class object I would instantiate for each contact. ContactList() would be the class that defines an array of Contact objects, and define methods to enter and retrieve information.
The problem is I'm not sure how to go about this. Would my approach stated above work? I'm not quite sure how to go about this and any suggestions and ideas would be greatly appreciated.
Here are my thoughts on this, with some pseudocode to help.
The following class is a basic implementation for what a contact should consist of based on the requirements. I opted for using String fields since this is just a homework problem and requires no extra engineering.
public class Contact
{
private String firstName;
private String lastName;
private String email;
private String zipCode;
public Contact()
{
//initialize all variables to empty string
}
public Contact(String firstName,String lastName, String email, String zipCode)
{
//Use this.variableName to set values
}
//getters/setters
}
public class Assignment1 //Or whatever assignment number this is == Main()
{
List<Contact> contacts;
public static void main(String[] args)
{
//Retrieve user input
// Execute rest of program
}
void printContacts(List<Contact> contacts)
{
foreach(Contact in contacts)
{
print(Contact.toString());
}
}
Contact getContactByLastName(String lastName)
{
foreach(Contact in contacts)
{
if(Contact.lastName == lastName)
return Contact;
}
else
Contact does not exist
}
void addContact(Contact contact)
{
contacts.add(contact);
}
}
I would have the ContactList only habe the required methods that make sense:
interface ContactList {
void add(Contact)
List<Contact> getList()
Contact getContactByLastName(String)
Contact getContactByEmail(String)
Contact getContactByZipCode(String)
}
then you can implement that interface with, lets say, an ContactArrayList that uses an ArrayList<Contact> for the backing object.
I would have your ContactList implement a generic list
public class ContactdList implements List<Contact>
but yeah, that sounds like it would work. I assume this is for a class, you don't want to get too far afield of what the the teacher has asked for/taught.

Categories