Adding object to an array list in Java - java

I am trying to add an object to an array list and have the following -
public static void main(String[] args) {
authors Authors = new authors();
ArrayList<authors> tabAuthors = new ArrayList<authors>();
Authors.setAuthId(1);
Authors.setAuthName("Roald Dahl");
System.out.println(Authors.toString());
tabAuthors.add(Authors);
Authors.setAuthId(2);
Authors.setAuthName("Julia Donaldson");
System.out.println(Authors.toString());
tabAuthors.add(Authors);
for (int counter =0; counter < tabAuthors.size(); counter++) {
System.out.println(tabAuthors.get(counter).getAuthId() + " " + tabAuthors.get(counter).getAuthName() );
}
}
}
The authors class
public class authors {
private int authId;
private String authName;
public int getAuthId() {
return authId;
}
public void setAuthId(int authId) {
this.authId = authId;
}
public String getAuthName() {
return authName;
}
public void setAuthName(String authName) {
this.authName = authName;
}
#Override
public String toString() {
return "authors{" +
"authId=" + authId +
", authName='" + authName + '\'' +
'}';
}
}
I was expecting the code to return -
1 Roald Dahl
2 Julia Donaldson
Instead, I am getting -
2 Julia Donaldson
2 Julia Donaldson
Why is the array list not reflecting the first object values ?

Because you create only one object and override second time when you set properties.
You need to create new object when you insert second object.

You are setting the value Julia Donaldson on the same Object. reference the variable Authors to a new object and the problem is solved.
authors Authors = new authors();
ArrayList<authors> tabAuthors = new ArrayList<authors>();
Authors.setAuthId(1);
Authors.setAuthName("Roald Dahl");
System.out.println(Authors.toString());
tabAuthors.add(Authors);
Authors = new Authors(); //Reference Authors to a new object here, or else
//you're using the same object and you'll overwrite the value Roald Dahl with
//Julia Donaldson
Authors.setAuthId(2);
Authors.setAuthName("Julia Donaldson");
System.out.println(Authors.toString());
tabAuthors.add(Authors);

In addition to the answer above by #Maurice, you can also add a constructor in authors class to set values for every object.
public authors(int authId, String authName) {
super();
this.authId = authId;
this.authName = authName;
}
In your main(), create two objects as below and add them to the list:
public static void main(String[] args) {
Authors authors1 = new Authors(1, "Roald Dahl");
Authors authors2 = new Authors(2, "Julia Donaldson");
List<Authors> tabAuthors = new ArrayList<Authors>();
System.out.println(authors1.toString());
tabAuthors.add(authors1);
System.out.println(authors2.toString());
tabAuthors.add(authors2);
for (int counter = 0; counter < tabAuthors.size(); counter++) {
System.out.println(tabAuthors.get(counter).getAuthId() + " " + tabAuthors.get(counter).getAuthName());
}
}
Output:
authors{authId=1, authName='Roald Dahl'}
authors{authId=2, authName='Julia Donaldson'}
1 Roald Dahl
2 Julia Donaldson

Thanks for your prompt responses.
I added the below in the code as I need to add indeterminate number of objects -
tabAuthors.add(new authors(authId,authName,authCountry,numBooks));
and declared authId,authName,authCountry,numBooks as variables.
The object values are being fetched from a database table.

Related

Why the output is different, java inheritance?

I've got 2 classes, car extends vehicle, Why, when I'm trying to print a new created car object the output isn't equal as I thought.
I'm running it on Eclipse, java 11
public class vehicle_13 {
private int years;
public vehicle_13(int y) {
years=y;
}
public int years() {
return years;
}
public String driving() {
return "Can drive";
}
public int speed() {
return 50;
}
public String toString() {
return "years = "+years()+"\n"+this.driving()+"\n"+"speed = "+this.speed()
+"\n"+this.money_per(); // driving() = this.driving()
}
public int money_per() {
return years*10;
}
}
public class car_13 extends vehicle_13 {
public car_13(int y) {
super(0);
}
public int speed() {
System.out.println(super.driving());
return super.speed()*2;
}
}
I expect the output of this car object .toString() to be:
years = 0
Can drive
Can drive
speed = 100
0
but the actual output is:
Can drive
years = 0
Can drive
speed = 100
0
When you concatenate the string like this:
return "years = " + years() + "\n" + this.driving() + "\n"
+ "speed = " + this.speed() + "\n" + this.money_per();
It has to execute each of the methods before it creates the string. After all, it's the result of executing the method that gets added to the string. So the println in the speed method is called when this.speed() is evaluated, then the concatenated string is returned by toString, and then the result is passed to System.out.println. So the println in speed runs before the println in main, not in the middle of it.
P.S: Long concatenation like this, is better suited to the String.format method
return String.format("years = %d\n%d\nspeed = %d\n%d",
years(), driving(), speed(), money_per());
You have called super.driving in the sub-class and that is what is evaluated first. Therefore it prints out "Can drive" first, before the result of the toString as you expected.

How to pass two parameter from 1 class to another in a function?

This is one of the class where i assign data to the item and it return one parameter back to the other class. How should i write it to return two parameter instead? For this case it return final price, how should i write it to return final price and subtotal as well?
public static String Final_Price = " ";
public static String subtotal = " ";
protected String doInBackground(String... arg0) {
Final_Price = co.price;
subtotal = co.subtotal;
return Final_Price;
}
#Override
protected void onPostExecute(String result){
String search = Final_Price;
((ReceiptActivity)activity).get_data(search);
}
This is the receipt activity where there is a function to get the data i pass.
public void get_data (String c)
{
shippingfeeTextView.setText("Shipping fee: " + c);
}
If you want only two parameters, you can use Pair. Source: http://developer.android.com/reference/android/util/Pair.html
You can create your own custom object like this
public class Result{
public String finalPrice, subTotoal;
public Result(String st, String fp) {
this.subTotal= st;
this.finalPrice= fp;
}
}
Then you can return Result object instead
Result res = new Result (x, y);
return res
You can return it as array, object or you can create a model and pass the model as parameter.
Assuming the two return values you want are the same data type, it's best not to over think things.
Just return a simple array:
double[] finalPrice = new double[2];
finalPrice[0] = co.price;
finalPrice[1] = co.subtotal;
return finalPrice;
or if you need to keep it a string:
String[] finalPrice = new String[2];
finalPrice[0] = ""+co.price;
finalPrice[1] = ""+co.subtotal;
return finalPrice;
This would be the simplest and most effective way to handle returning multiple values.
To use your array is simple as well:
public void get_data (String[] c)
{
shippingfeeTextView.setText("Shipping fee: " + c[0]+"subtotal: "+c[1]);
}
If the values are different data types, just create an encapsulated data class with the appropriate fields, getters / setters, and return it's constructor:
return new CustomContainer(myDouble, anInteger);
Your get method would then look something like this:
public void get_data (CustomContainer c)
{
shippingfeeTextView.setText("Shipping fee: " + c.getSalePrice()+"subtotal: "+c.getSubTotal());
}

Java Object Without a Class

I don't know if this is possible in Java but I was wondering if it is possible to use an object in Java to return multiple values without using a class.
Normally when I want to do this in Java I would use the following
public class myScript {
public static void main(String[] args) {
// initialize object class
cl_Object lo_Object = new cl_Object(0, null);
// populate object with data
lo_Object = lo_Object.create(1, "test01");
System.out.println(lo_Object.cl_idno + " - " + lo_Object.cl_desc);
//
// code to utilize data here
//
// populate object with different data
lo_Object = lo_Object.create(2, "test02");
System.out.println(lo_Object.cl_idno + " - " + lo_Object.cl_desc);
//
// code to utilize data here
//
}
}
// the way I would like to use (even though it's terrible)
class cl_Object {
int cl_idno = 0;
String cl_desc = null;
String cl_var01 = null;
String cl_var02 = null;
public cl_Object(int lv_idno, String lv_desc) {
cl_idno = lv_idno;
cl_desc = lv_desc;
cl_var01 = "var 01";
cl_var02 = "var 02";
}
public cl_Object create(int lv_idno, String lv_desc) {
cl_Object lo_Object = new cl_Object(lv_idno, lv_desc);
return lo_Object;
}
}
// the way I don't really like using because they get terribly long
class Example {
int idno = 0;
String desc = null;
String var01 = null;
String var02 = null;
public void set(int idno, String desc) {
this.idno = idno;
this.desc = desc;
var01 = "var 01";
var02 = "var 02";
}
public int idno() {
return idno;
}
public String desc() {
return desc;
}
public String var01() {
return var01;
}
public String var02() {
return var02;
}
}
Which seems like a lot of work considering in Javascript (I know they are different) I can achieve the same effect just doing
var lo_Object = f_Object();
console.log(lo_Object["idno"] + " - " + lo_Object[desc]);
function f_Object() {
var lo_Object = {};
lo_Object = {};
lo_Object["idno"] = 1;
lo_Object["desc"] = "test01";
return lo_Object;
}
NOTE
I know the naming convention is wrong but it is intentional because I have an informix-4gl program that runs with this program so the coding standards are from the company I work for
The best way to do this is to use HashMap<String, Object>
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Object> person =
new HashMap<String, Object>();
// add elements dynamically
person.put("name", "Lem");
person.put("age", 46);
person.put("gender", 'M');
// prints the name value
System.out.println(person.get("name"));
// asures that age element is of integer type before
// printing
System.out.println((int)person.get("age"));
// prints the gender value
System.out.println(person.get("gender"));
// prints the person object {gender=M, name=Lem, age=46}
System.out.println(person);
}
}
The advantage of doing this is that you can add elements as you go.
The downside of this is that you will lose type safety like in the case of the age. Making sure that age is always an integer has a cost. So to avoid this cost just use a class.
No, there is no such a feature, you have to type out the full type name(class name).
Or use may use val :
https://projectlombok.org/features/val.html
Also, if you use IntelliJ IDEA
try this plugin :
https://bitbucket.org/balpha/varsity/wiki/Home
I am not sure if it's possible with Java. Class is the primitive structure to generate Object. We need a Class to generate object. So, for the above code, i don't think there is a solution.
Java methods only allow one return value. If you want to return multiple objects/values consider returning one of the collections. Map, List, Queue, etc.
The one you choose will depend on your needs. For example, if you want to store your values as key-value pairs use a Map. If you just want to store values sequentially, use a list.
An example with a list:
list<Object> myList = new ArrayList<Object>();
myList.add("Some value");
return myList;
As a side note, your method create is redundant. You should use getters and setters to populate the object, or populate it through the constructor.
cl_Object lo_Object = new cl_Object(1, "test01");
The way you have it set up right now, you're creating one object to create another of the same type that has the values you want.
Your naming convention is also wrong. Please refer to Java standard naming convention:
http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-135099.html#367

Object Oriented Programming, Method Call Not Working as Expected, Subclasses

I am having trouble with my call to the method makeNoise in the Pets class. I call the makeNoise method through another class, Humans, that has a makePetMakeNoise method:
public void makePetMakeNoise()
{
int randnum = (int)(Math.random() *5);
pet.makeNoise(randnum);
}
And I set the pets' canMakeNoise boolean when I create it: Cat a = new Cat("Critter", "Meow", true);
When I call the Humans' makePetMakeNoise method, I only get a printout like so: Critter remains silent instead of: Meow Critter. Why is this, and how do I fix it? Thanks.
public class Pets
{
String name;
String noise;
boolean canMakeNoise;
public Pets(String pname, String pnoise, boolean pcanmakenoise)
{
name = pname;
noise = pnoise;
pcanmakenoise = canMakeNoise;
}
public void makeNoise(int number)
{
if(canMakeNoise==true)
{
for(int i=0; i<number; i++)
{
System.out.println(noise + " " + name);
}
}
else if(canMakeNoise==false)
{
System.out.println(name + " *remains silent*");
}
}
public void eat()
{
System.out.println(name + " is eating...");
}
}
It looks like the assignment for "canMakeNoise" in the constructor is reversed, i.e. assign canmakenoise = pcanmakenoise.
Change this line from
pcanmakenoise = canMakeNoise;
to
canMakeNoise = pcanmakenoise;
You assigned the constructor parameter pcanmakenoise with the value of canMakeNoise which is currently null.
pcanmakenoise = canMakeNoise;
Default boolean value is false.
canMakeNoise is always false; Hence below condition is always called.
else if(canMakeNoise==false)
Reference ::
https://msdn.microsoft.com/en-us/library/83fhsxwc.aspx
https://www.google.com/search?q=c%23+default+boolean+value&ie=utf-8&oe=utf-8

extending a class with an extra parameter

I got a simple question. I have a class, which I use for purpose of splitting a string in 2 years:
public class Period {
int firstYear;
int secondYear;
Period () {
}
Period(String periode) {
String [] periodeSplit = periode.split("-");
this.firstYear = Integer.parseInt(periodeSplit[0]);
this.secondYear = Integer.parseInt(periodeSplit[1]);
}
public String toString() {
return "Firstyear: " + this.firstYear + "\n" + "Secondyear: " + this.secondYear;
}
}
I now want to extend this class, not splitting the data into 2 different ints but into 3 different ints. So besides the 2 already exisiting integer vars I want one extra. Whats the easiest way of doing this?
Your help is appreciated!
Kind regards,
Kipt Scriddy
I think it would be better (and quite easy) the create more general class that will be able to deal with any number of years you pass to it:
public class Period {
int[] years;
Period() {
}
Period(String periode) {
String[] periodeSplit = periode.split("-");
years = new int[periodeSplit.length];
for (int i = 0; i < periodeSplit.length; i++) {
years[i] = Integer.parseInt(periodeSplit[i]);
}
}
public String toString() {
String result = "";
for (int i = 0; i < years.length; i++) {
result += "Year " + i + ":" + years[i] + "\n";
}
return result;
}
}
If the original class really have to be extended than it can be done like this:
class ExtendedPeriod extends Period {
int thirdPart;
ExtendedPeriod(String periode) {
String[] periodeSplit = periode.split("-");
this.firstYear = Integer.parseInt(periodeSplit[0]);
this.secondYear = Integer.parseInt(periodeSplit[1]);
this.thirdPart = Integer.parseInt(periodeSplit[1]);
}
public String toString() {
return "Day: " + this.firstYear + "\n" + "Month: " + this.secondYear
+ "\nYear: " + this.thirdPart;
}
}
I would recommand to change variable names 'firstYear' and 'secondYear' to something different, like 'firstPart', 'secondPart' because for extendedPeriod they aren't years anymore (I left them in my code so it would compile with yours but called the new int 'thirdPart'). I don't feel that this is the best use of inheritance but if that's what's needed. I also wanted to reuse toString from Period like this:
public String toString2() {
return super.toString() + "\nThird part: " + this.thirdPart;
}
but for it to have sense you would have to chagne toString method in Period not to call values 'years'.
When you extend the class, split it into two variables first, the one that's different from your current code, and then the one that your current code would handle.
Then simply call super(periode)
The child class will have access to the parent variables, since you made them default.
I wouldn't extend to just add a new year.
Why not make the entire thing generic enough, so that it supports whatever split you need.
public class Period {
String [] periodeSplit;
Period(String periode) {
periodeSplit = periode.split("-");
}
public String toString() {
//TODO : Iterate and print.
}
}

Categories

Resources