Updating elements in an ArrayList in Java? - java

I have the following class:
public class Profile{
String name, age, location;
}
Say that I then have the following code:
ArrayList<Profile> profiles = somePopulatedArrayList;
Profile profile = profiles.get(1);
profile.name = "New name here";
My question is when I have the above, is the .name of the object in the ArrayList getting updated, or am I creating a completely new object here and only changing the .name of that object while the Profile object stored in the ArrayList still has the old name?
I'm trying to edit properties of objects in the ArrayList and I'm wondering if the above approach is correct or not?

No new object was created. You've updated the object in the list, that is, the object in the list will have "New name here" as name.
In fact this you could test and see with a debugger.

No New Object is Created, you are modifying the existing value.
In fact this is not a good practice,you should allow access to your
class variables directly, make them as private and provide
setter/getter methods for the same.
public class Profile {
private String name, age, location;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}

In Java, all variables that are object types hold references to objects. When you call get on a collection, it returns a reference to the object that's inside it, so if you then proceed to modify that object, the changes will be seen by anyone else looking at the same object.

Related

Setting objects as partners within the same class in java

As a task in my beginners course in object oriented programming, I must set two objects in my Partner class as "married".
This is my attempt at beginning:
public class Partner {
String name;
String partner;
public Partner(String name, String partner) {
super();
this.name = name;
this.partner = partner;
}
public String getPartner() {
return partner;
}
public void setPartner(Partner()) { //think i need the object here?
this.partner = partner; //however i don't know how
}
public String getName() {
return name;
}
public static void main(String[] args) {
Partner p1 = new Partner("Name1", idk);
Partner p2 = new Partner("Name2", idk);
}
}
My issue is that I don't know how to use the object in the setPartner method, if that's even the correct way to do it. It should also be possible to get a divorce from the other object by setting one of the objects' partner to null.
It should also make it so that the partners automatically register as married to eachother if one of them is set a married to the other. For example, if p1 is set as the partner of p2, p2 should automaticly be set as the parter to p1 as well.
Create two constructors: one with just name and another with name and partner (of type, Partner) so that you will have the flexibility to initialize an object with just name and then set its partner or initialize with name and partner (if the partner is known).
public class Partner {
private String name;
private Partner partner;
public Partner(String name) {
this.name = name;
}
public Partner(String name, Partner partner) {
this.name = name;
setPartner(partner);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPartner(Partner partner) {
partner.partner = this;
this.partner = partner;
}
#Override
public String toString() {
String value;
if (partner != null) {
value = name + ", partner=" + partner.name;
} else {
value = name;
}
return value;
}
public static void main(String[] args) {
// Example 1
Partner p1 = new Partner("Name1");
Partner p2 = new Partner("Name2");
p1.setPartner(p2);
System.out.println(p1);
System.out.println(p2);
// Example 2
Partner p3 = new Partner("Name3");
Partner p4 = new Partner("Name4", p3);
System.out.println(p3);
System.out.println(p4);
}
}
Output:
Name1, partner=Name2
Name2, partner=Name1
Name3, partner=Name4
Name4, partner=Name3
Are you asking how to write setter methods ? Something like this
public void setPartner(String partner) {
this.partner= partner;
}
If you intend for a Partner object to have a pointer to another object of this class, you should change String partner to Partner partner.
You won't always have an initialized Partner object to use in the Partner constructor, so you have 3 options:
add another constructor which doesn't require an argument of type Partner
change the existing constructor
pass null as argument.
In any case, you'll have to initialize the partner field somewhere else.
That's where setters come in. The correct syntax for your setPartner function would be:
public void setPartner(Partner partner) {
this.partner = partner;
}
getPartner() function should be changed accordingly to return the correct type.
Your code in main() can then be something like this:
Partner p1 = new Partner("Name1", null);
Partner p2 = new Partner("Name2", p1);
p1.setPartner(p2);
It should also be possible to get a divorce from the other object by setting one of the objects' partner to null.
That is accomplished by using p.setPartner(null), where p is an object of type Partner. You might also want to set both objects partners to null instead of just one, for easier checking.

Loop over object setters java [duplicate]

This question already has answers here:
Invoking all setters within a class using reflection
(4 answers)
Closed 5 years ago.
I have a POJO object and a collection of appropriate data.
import java.util.ArrayList;
import java.util.List;
public class TestPojo {
private String name;
private String number;
private String id;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public static void main(String[] args) {
TestPojo test = new TestPojo();
List<String> sampleData = new ArrayList<>();
sampleData.add("Bob");
sampleData.add("641-613-623");
sampleData.add("id-1451");
sampleData.add("Male");
test.setName(sampleData.get(0));
test.setNumber(sampleData.get(1));
test.setId(sampleData.get(2));
test.setSex(sampleData.get(3));
}
}
My question is how can i fill my POJO object with data in a loop? Is it posible to iterate all object setters and set data from List in appropriate places? I know that reflection can help in this case.
Here is an simple example to call setters via reflection (which needs to be adjusted):
[if this is a good approach, is another question. But to answer your question:]
public static void main(String[] args) throws Exception
{
//this is only to demonstrate java reflection:
Method[] publicMethods = TestPojo.class.getMethods(); //get all public methods
TestPojo testObj = TestPojo.class.newInstance(); //when you have a default ctor (otherwise get constructors here)
for (Method aMethod : publicMethods) //iterate over methods
{
//check name and parameter-count (mabye needs some more checks...paramter types can also be checked...)
if (aMethod.getName().startsWith("set") && aMethod.getParameterCount() == 1)
{
Object[] parms = new Object[]{"test"}; //only one parm (can be multiple params)
aMethod.invoke(testObj, parms); //call setter-method here
}
}
}
You can also save all setter-methods in an list/set for later re-use...
But as others already said, you have to be careful by doing so (using reflection)!
Cheers!
You can't easily - and you shouldn't.
You see, your POJO class offers some setters. All of them have a distinct meaning. Your first mistake is that all of these fields are strings in your model:
gender is not a string. It would rather be an enum.
"number" is not a string. It should rather be int/long/double (whatever the idea behind that property is)
In other words: you premise that "input" data is represented as array/list is already flawed.
The code you have written provides almost no helpful abstractions. So - instead of worrying how to call these setter methods in some loop context - you should rather step back and improve your model.
And hint: if this is really about populating POJO objects from string input - then get your string into JSON format, and use tools such as gson or jackson to do that (reflection based) mapping for you.
"Iterating over methods" seems pretty much of a wrong idea in OO programming. You could simply add a constructor to your class setting all of your attributes, and then just call that constructor in a loop as desired to create new objects with data you desire.
In your class define:
public TestPojo(String name, String number, String id, String sex){
this.name = name;
this.number = number;
this.id = id;
this.sex = sex;
}
Also using a List makes no much sense here. I'd recommend using a HashMap to then iterate over it in a for loop making proper calls of the above constructor.

I am trying to print the name of the list but somehow the reference from the arraylist is not working?

Customer is a class. The Class list is arraylist of Customer.
I have added the Customers to list but when I want to print all the customer names from the list I get null only.
import java.util.*;
public class Assignment1 {
public static void main(String args[])
{
List list = new List();
list.addCustomer("man");
list.addCustomer("man");
//System.out.println(list);
list.printx();
}
}
class Customer{
public String name;
public Customer(String name)
{
name = this.name;
}
}
class List
{
ArrayList<Customer> list = new ArrayList<Customer>();
public void addCustomer(String name1)
{
Customer x = new Customer(name1);
list.add(x);
System.out.println(list.get(0));
}
public void printx()
{
for(int i =0;i < list.size();i++)
{
System.out.println(list.get(i).name);
}
}
}
Inside your Customer constructor, you need to set ::
this.name = name;
and not the other way round! :P
What you have done right now is that you change the function parameter name to the class parameter name which is currently null(default initialization). So, you never initialize name variable of the Customer class, and hence you always get null when you print it.
I suggest you override the toString method in class Customer, it helps you debug your Customer objects. For example, you can change the local variable to assignedName as below:
class Customer{
public String name;
public Customer(String name)
{
this.name = name;
}
#Override
public String toString(){
return "customer name:" + this.name;
}
}
this.name and name are different things in the Customer constructor:
this.name is an instance variable and name is a local variable defined in your constructor.
// you should narrow the modifier to private, and implement getter and setter for it
public String name;
public Customer(String assignedName){
this.name = assignedName;
}

How to set and retrieve ArrayList when used as a member variable of another object

I have following code:
public class Address {
private String city;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
And I have another class User with ArrayList<Address> as member variable as follows.
import java.util.ArrayList;
public class User {
private String name;
private ArrayList<Address> listOfAddresses ;
public ArrayList<Address> getListOfAddresses() {
return listOfAddresses;
}
public void setListOfAddresses(ArrayList<Address> listOfAddresses) {
this.listOfAddresses = listOfAddresses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And in the class with the main method, I have created user object which has two member variable such as name and listofAddresses. Now, I need some guidance about how to set value for listOfAddresses using user object. And also how to retrieve using user object.
My main class looks like this.
import java.util.ArrayList;
public class ArrayImpl {
public static void main(String[] args) {
User user = new User();
user.setName("First User");
Address address = new Address();
address.setCity("Melbourne");
user.setListOfAddresses(address);
}
}
And I'm getting error at the user.setListofAddressess(address) as:
The method setListOfAddresses(ArrayList) in the type User is
not applicable for the arguments (Address)
My understanding is that listOfAddresses is an ArrayList of type Address and thus I'm trying to use setter method of listOfAddresses member variable to set it's value.
Can somebody please help me how to set listOfAddresses and retrieve using user object.
You have primarily two options:
Ugly Way
You retrieve the current list of addresses by calling the Getter, then adding your new address, then calling the Setter with your new list:
List<Address> addresses = user.getListOfAddresses();
addresses.add(address);
user.setListOfAddresses(addresses);
The smart and cool way
Your class User provides delegates to add and remove Addresses. For this, add methods for your purposes in your User class:
public void addAddress(Address a) {
this.listOfAddresses.add(a);
}
You are trying to set variable of type 'address' in user object but you are supposed to set an object of type ArrayList their.
User user = new User();
ArrayList<Address> ar=new ArrayList<>();
Address ad1=new Address();
ad1.setCity("Melbourne");
ar.add(ad1);
user.setListOfAddresses(ar);
Your method definition for setListOfAddresses in User class takes as argument an object of type ArrayList<Address>, but in your main you're trying to pass it an instance of Address.
This is the right approach:
ArrayList<Address> addrList = user.getListOfAddresses();
if (addrList == null) {
//If it's the first address you insert, you have to initialize the ArrayList
addrList = new ArrayList<Address>();
}
addrList.add(address);
Then to retrieve each address i straightforward:
ArrayList<Address> addrList = user.getListOfAddresses();
for (Address a : addrList) {
//do something with a....
}

How to use Parcelable for a class which has multiple constructors?

Well, i was trying to pass arraylist of objects from one activity to another. I have 2 constructors in the class Student.
If, i use, Serializable than the code is like below:
#SuppressWarnings("serial")
public class Student implements Serializable
{
private int studentdID;
private String studentName;
private String studentDept;
public Student(){}
public Student(String name, String dpt)
{ this.studentName = name;
this.studentDept = dpt;}
public Student(int id, String name, String dpt)
{ this.studentdID = id;
this.studentName = name;
this.studentDept = dpt; }
public int getstudentdID() { return studentdID; }
public void setstudentdID(int studentdID) {this.studentdID = studentdID;}
public String getstudentName() { return studentName;}
public void setstudentName(String studentName) {this.studentName = studentName;}
public String getstudentDept() { return studentDept; }
public void setstudentDept(String studentDept) { this.studentDept = studentDept;}
}
But the problem i am facing is that how am i going to do this with parcelable? How am i going to set the values of the variables in class-like i did with Serializable? I mean separately using 2 constructors-one without ID another without the ID?
Did you read how Parcelable works?
You need only one constrcutor for parcelable to read what you pass to it, and Parcelable interface will add a method writeToParcel where you put the data to save.
It's not an automatic process like Serializable, everything is up to you.
The constructor which Parcelable will use will accept only one argument Parcel where you will find some methods like read*(KEY) to read back values.
And in writeToParcel you will write in the Parcel (the argument of the method) the values you want pass to pass with write*(KEY, VALUE).
Parcelable don't care about your constructors or fields.
P.S You will need a CREATOR too. Read some tutorial online to know more about it if you need.
Marco's answer explains why Parcelable doesn't automatically decide what constructor to use - it can't.
However, there is a way around this. Use Parcel.dataAvail(), which
Returns the amount of data remaining to be read from the parcel. That
is, dataSize()-dataPosition().
For example,
public Student(){}
public Student(String name, String dpt)
{
this.studentName = name;
this.studentDept = dpt;}
public Student(int id, String name, String dpt)
{ this.studentdID = id;
this.studentName = name;
this.studentDept = dpt;
}
public Student(Parcel in) {
name = in.readString();
dpt = in.readString();
if(in.dataAvail() > 0) // is there data left to read?
id = in.readInt();
}
^ The above constructor will allow for the necessary variables to be instantiated correctly. Also, you define writeToParcel() something like:
public void writeToParcel(Parcel out) {
out.writeString(name);
out.writeString(dpt);
//0 is the default value of id if you didn't initialize it like
// in the first constructor. If it isn't 0, that means it was initialized.
if(id != 0)
out.writeInt(id);
}
Of course, you'll need to define your CREATOR like so:
public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() {
public Student createFromParcel(Parcel in) {
return new Student(in);
}
public Student[] newArray(int size) {
return new Student[size];
}
};
#u3l solution is not required..how many constructors are there it doesn't matter.
simple it works go as normal implementation.
I mean no special care is required when multiple constructors present in parcelable.

Categories

Resources