This question already has answers here:
What is a raw type and why shouldn't we use it?
(16 answers)
Closed 6 years ago.
I have a program that creates a couple objects and adds each one to an ArrayList, then is supposed to loop over each object in the ArrayList and use a getter from another class within the project to display information on each object. I can't get the objects in my foreach loop to use any of the methods in my other class. Here is my main, including the trouble loop at the bottom:
import java.util.ArrayList;
public class ITECCourseManager {
public static void main(String[] args) {
ArrayList ITECCourse = new ArrayList();
ITECCourse infotech = new ITECCourse("Info Tech Concepts", 1100, 5, "T3050");
infotech.addStudent("Max");
infotech.addStudent("Nancy");
infotech.addStudent("Orson");
ITECCourse.add(infotech);
ITECCourse java = new ITECCourse("Java Programming", 2545, 3, "T3010");
java.addStudent("Alyssa");
java.addStudent("Hillary");
ITECCourse.add(java);
for (Object course : ITECCourse) {
System.out.println("Name: " + course.getName());
}
}
}
And here is the other class in my project with the method I need to use:
public class ITECCourse {
public String name;
public int code;
public ArrayList<String> students;
public int maxStudents;
public String room;
ITECCourse(String courseName, int courseCode, int courseMaxStudents, String roomNum) {
name = courseName;
code = courseCode;
maxStudents = courseMaxStudents;
students = new ArrayList<String>();
room = roomNum;
}
public String getName() {
return name;
}
If I replace course.getName() with java.getName(), the code works. I'm confused why I can't use a foreach loop across the ArrayList to use the getter for each object, when I am able to call the object and use the method directly from the same place in the code.
Edit: Thank you for the answers, simple mistake only had to make two/three changes: declare ArrayList<ITECCourse> at the beginning, change Object in for loop to ITECCourse, and of course change my arraylist from ITECCourse to ITECCourseList so there isn't confusion with my ITECCourse class.
The call to course.getName() doesn't work because you've defined course as an Object in your loop and Object doesn't have the method getName(). If you add a type parameter to your ArrayList declaration such as ArrayList<ITECCourse>, then you can iterate over the list of ITECCourse instances rather than Object.
On a side note, naming your variable ITECCourse will just lead to confusion because it's the same as your class. Might be better to name your variable something like itecCourseList.
Related
I'm basically making a class for each university course where any number of students can apply. I wanted to know how can I have a constructor where it doesn't matter if my number of 'Student' objects is 1 or 15 or more...cause I know there's a way, just can't remember it...
import java.util.ArrayList;
public class Course {
String name;
ArrayList <Student>listofstudents=new ArrayList<>();
int noofStudents;
//The class Student is defined.
Course(String name,Student s1, Student s2){
this.name=name;
listofstudents.add(s1);
listofstudents.add(s2);
//Do I have to do this for every possible number of student?
}
}
As your other answer observes, constructors can have variable arguments just like regular methods can have. However, you should consider just saying no. That is, the students enrolled in a given course are a secondary attribute, and you can put a Course into a valid state without them. Consider, then, not accepting the students via the constructor, but instead having one or more methods to add students to existing Courses. (You might need that anyway.) Then just add the students via that route after initializing the Course.
void addStudent(Student s) {
listofstudents.add(s);
}
void addStudents(Student ... s) {
if (s != null) {
listofstudents.addAll(java.util.Arrays.asList(s));
}
}
You can use varargs. Variable Arguments is a technology that allows you to create methods with an arbitrary number of arguments.
import java.util.ArrayList;
public class Course {
String name;
ArrayList <Student>listofstudents=new ArrayList<>();
int noofStudents;
//The class Student is defined.
Course(String name,Student ... s){
Student [] stds = s;
this.name=name;
//your code
}
}
Varargs are straightforward to use. But there're a few rules we have to keep in mind:
Each method can only have one varargs parameter
The varargs argument must be the last parameter
Every time we use varargs, the Java compiler creates an array to hold the given parameters.
Now you can use the constructor in this way:
new Course("Name");
new Course("Name", new Student());
new Course("Name", new Student(), new Student(), new Student());
The following class has an array of integer
public class customers {
public static int ID[];
public customers(int ID[]) {
ID = new int[10];
ID[0] = 00245;
ID[1] = 76644;
// more
}
//getters and setters
The subclass is defined as follow
public class songs extends customers {
//bunch of fields
The issue rises when within my array of objects. To create it, the following constructor was needed
public songs(int ID, // bunch of fields {
super(ID[0]);
this.ID = ID[];
// bunch of fields
Here, the super() method throws me back an error, that int[] in customers cannot be defined as a simple int.
Same goes when populating my array :
arraylist.add(new songs(ID[0], ...)); // didnt paste other variables
ID[0] is considered a simple int and not a int[].
While I understand the error itself, I don't know what causes it nor how to make java use my array of customers within the arrayList of Object defined in songs.
Thanks in advance !
If you want to send an array through subclass constructor you must first have a non-static (instance) array field in your super class, like this:
private int[] ids;
Be noticed that in java the fields are usually defined in camel case format.
Also you have a syntax error in this line:
super(ID[0])
You are referencing the int parameter defined in songs constructor as if an array, that is not correct.
Your call on super(ID[0]); is wrong: it calls the constructor of your members class, sending to it an int rather than an int[] as specified by your constructor. Moreover, I believe this.ID = ID[]; is wrong as well: "ID[]" in this context doesn't represent anything.
Also, as mentioned, static is probably not the good approach: it means that all Objects of type "Members" will share the same one-and-unique attribute "ID[]"!
More code would help. Especially about your songs, and the "arraylist" you're talking about.
This question already has answers here:
Why does my ArrayList contain N copies of the last item added to the list?
(5 answers)
Closed 6 years ago.
Having some trouble with a program I'm trying to write to imitate the card game 'Top Trumps', more specifically adding the Attributes of each Card to the ArrayList held by my class Card.
for (int i=1; i<5;i++)
{
int tempVal = rn.nextInt(10);
Card.attrbts.add(new Attribute ("Attribute "+i, tempVal));
System.out.println("Name: "+Attribute.name + " Value: " + tempVal); //debug
}
The program is supposed to randomly generate the value of each attribute and for simplicity I am just naming the each Attribute 'Attribute + i'.
The loop executes as expected for the most part, the value and names are generated fine as I can see from the debug statement, however, while this loop is adding elements to the ArrayList in my Card class it's using the same name and value for each element in the list, specifically the final iteration of my for loop (e.g. Attribute 4 and 6).
I was wondering if one of you could help explain to me why this is happening and how I'd go about fixing it?
Cheers
EDIT:
public class Card {
static ArrayList<Attribute> attrbts = new ArrayList<Attribute>();
String name;
public Card(String n, ArrayList<Attribute>attr)
{
this.name = n;
this.attrbts = attr;
}
public class Attribute {
static String name;
static int val;
public Attribute(String n, int v){
this.name = n;
this.val = v;
}
You are using static fields name and val. Static fields are shared by all objects of that class.
Instead, you want each object/instantiation to have its own version.
For this, simply remove static.
public class Attribute {
String name;
int val;
…
}
(You should probably have got a warning in your Attribute constructor for accessing the static fields through a non-static reference).
There a plenty of resources on static fields. For instance have a look at Java Static vs Instance (thanks to Murat for pointing to this question).
Your debug print statement won't work, as you accessing the field in a static way Attribute.name.
If you would want to access that field, you have to query the attribute object directly. For instance by saving it into a variable like this:
Attribute attr = new Attribute(…)
Card.attrbts.add(attr);
System.out.println("Name: " + attr.name + …)
Drop the static modifiers. Every thing should then work perfectly.
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 6 years ago.
I am wondering if I can use for each loop to iterate through the object of a class. for instance, I created an object honda of type car. I append all the state of the car such as model, price, color, etc. to it. I want to print all the instance of the car. I don't want to use the print statement to print each instance . what is the best way to do it? Thanks.
Below is my java code
package classandobjects;
public class MainClass {
public static void main(String[] args) {
Classes friend1 = new Classes();
friend1.name="yusuf";
friend1.age=27;
friend1.country="Nigeria";
friend1.department="EE";
friend1.gender="male";
Classes friend2 = new Classes();
friend1.name="mathew";
friend1.age=30;
friend1.country="Nigeria";
friend1.department="EE";
friend1.gender="male";
FavPlayers player = new FavPlayers();
player.pname="J.Terry";
player.position="C.Back";
player.gaols=38;
player.awards="25-awards";
FavPlayers player1 = new FavPlayers();
player1.pname="F.Lampard";
player.position="Midfield";
player.gaols=50;
player.awards="10-awards";
Car model = new Car();
model.modelName="Honda Civic";
model.color="Ash-color";
model.Doors="4-doors";
model.price=900000;
System.out.println("below is my friend information");
System.out.println(friend1.name);
System.out.println(friend1.age);
}
}
You had better override a toString method in the Car class and simply print it like:
System.out.println(model);
Indeed, you needn't print each instance variable separately. Your toString may have the following view:
public #Override String toString() {
return modelName + " [" + color + ... + "]"; // also consider StringBuilder
}
If you came from languages where an object is an associative array (e.g. JavaScript) and asked how to print an instance using a foreach loop in Java, then the answer is that Java doesn't allow it (it is possible by reflection though) and you cannot iterate over object variables through a foreach.
I don't want to use the print statement to print each instance
Well, you're going to have to build up a string and print it somewhere.
what is the best way to do it?
If I understand correctly, you want to print an object?
Then implement a toString() method.
public class Classes {
// other code
public String toString() {
// change how you want
return this.name + ", " + this.age;
}
}
Then you can do
System.out.println(friend1);
If you want to print a list of objects, then you need a list to loop over. You could use reflection to get a list of object fields and values, but that seems unnecessary.
This question already has answers here:
How to avoid constructor code redundancy in Java?
(4 answers)
Closed 9 years ago.
Hi I am just learning about constructor chaining in Java and had some questions...
First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.
In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?
import java.util.*;
class Employee
{
private String name;
private double salary;
public Employee()
{
this("James Bond", 34000);
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public static void main(String[] args)
{
Employee a = new Employee();
}
}
Actually I believe the most common use of chained Constructors is when the Constructor does more than just setting the member variables.
static int numOfExamples = 0;
public Example(String name, int num)
{
this.name = name;
this.num = num;
numOfExamples++;
System.out.println("Constructor called.");
Log.info("Constructor called");
}
public Example()
{
this("James Bond",3);
}
That way we don't have to write the code for logging and incrementing the static variable twice, instead just chaining the constructors.
Chaining constructors like this is useful to avoid repeating code, and helps with maintainability:
public MyClass(int x, double y, String z) {
// set fields
}
public MyClass() { // i.e. a constructor that uses default values
this(42, 4.2, "hello world"); // x is 42, y is 4.2, and z is "hello world"
}
If we didn't use the chain, and wanted to change how the x argument (for example) is processed when constructing an instance of MyClass, we would have to change code in both constructors. With the chain, we only need to change one of them.
1) As others have said, it's for code maintenance, basically the idea is that you only write one piece of code once, which means you only need to edit it once, there is no risk of overlooking something when editing your methods and the two accidentally becoming different.
Personally I tend to use this differently than in your example. Like so:
Employee() {
setupStuff();
}
Employee(String name) {
this();
this.setName(name);
}
This is a nice way of doing things, because potentially your setter can be way more complicated than just setting a member in the class. So basically what this does is puts calling the empty constructor and then a setter into a single method, making it much easier for anyone using the class.
2) The constructor being called doesnt't create a different object at all, it creates this object. Note that there is no new keyword used. Basically you're just calling a different method inside your constructor, except that method happens to also be a constructor.
Every time you want to allow constructing an object wit default values, and also want to allow creating the same object with non-default values. Let's imagine a DateTime class. You could want to initialize it with the current time by default, or with a specific time. Imagine a Car class. You could imagine constructing it with Black as the default color, or with a specific color. This kind of situation is very common. See java.util.ArrayList or java.util.Locale, for concrete examples.
It's stored in the name field. So you access it, from the object itself, with this.name (this being optional, just as in the getName() method).
How do I access this new "James Bond" object for future use?
Because you saved the values of name and salary as fields of your employee class, then inside the employee class you can use those fields, and outside your employee class you can use the getter/setter methos of your employee class