I'm starting to learn java, and faced this problem when I can reach object name and lastName, but can't reach if I put them in object array.
public class Human {
String name;
String lastName;
String[] people;
People(String name, String lastName) {
this.name = name;
this.lastName = lastName;
};
public static People tom = new People("Tom", "Tommy");
public static People ted = new People("Ted", "Teddy");
public static Object[] objects = {
tom,
ted
};
public static void main(String[] args) {
System.out.println(tom.lastName);
System.out.println(objects[0]);
and this line I need does not work.
System.out.println(objects[0].lastName);
}
Simple: you declared that array of type Object.
Objects don't have names, only an instance of People has!
In other words: you want to declare an array of People, not Object.
You see, the compiler only "remembers" the type that is used on the left hand side of that variable declaration. It does not know that you in fact created an array of Object and placed solely instances of People inside that array.
And unrelated: people implies plural. You should rather call that class Person, or maybe PersonInfo.
Here, Object[] objects is an array of Object and Object class does not have anything like lastName. There is two way to solve the problem.
Declare the array as People[] objects
or
Cast the object to people like ((People)objects[0]).lastName
Related
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.
I missed one of my lectures in Java, and the subject was classes, methods, constructors etc. The homework is one task:
Create a class Person, objects of which describe persons, and which
contains only two felds: name (String) and year of birth (int). In
this class, define
constructor taking name and year of birth;
constructor taking only name and setting the year of birth to default value 1990;
method isFemale returning true if this person is a woman (we assume, not very sensibly, that only women and all women have names ending
with the letter 'a'); otherwise the method returns false;
static function getOlder taking two references to objects of class Person and returning the reference to the older of these two persons;
static function getOldest taking the reference to an array of references to objects of class Person and returning the reference to
the oldest person represented in the array;
static function getYoungestFemale taking the reference to an array of refe- rences to objects of class Person and returning the reference
to the youngest woman represented in the array, or null if there is no
woman in the array.
In a separate class, write a main function in which the whole
functionality of the class Person is tested.
I checked some tutorials and explanations, I didn't go straight here asking for help but after 2 hours of ripping my hair out I've been only able to come up with this:
public class Person {
String name;
int yob; //year of birth
public Person() {
Person jan = new Person("Jan", 1995); //the names are polish
Person joanna = new Person("Joanna", 1993);
Person michal = new Person("Michal", 1980);
Person beata = new Person("Beata", 1979);
Person kazimierz = new Person("Kazimierz", 1998);
Person magdalena = new Person("Magdalena", 1999);
}
public Person(String name, int yob) {
this.name = name;
this.yob = yob;
}
public Person(String name) {
this.name = name;
this.yob = 1990;
}
public static boolean isFemale(String name) {
if(name.equals("Joanna")) {
return true;
} else {
return false;
}
}
public static String getOlder(Person x?, Person y?) { // if I understand the task correctly, I should reference any two names?
if(x?.yob>y?.yob) {
return x?.name;
} else {
return y?.name;
}
//getOldest and getYoungestFemale methods go here
}
}
However, I can't wrap my head around the last three steps. My brain is literally boiling. It would really help if anyone could explain the last three bullet points (getOlder reference to any 2 people and getOldest/getYoungestFemale)
If you don't have time to explain, some example of a "method taking a reference to an array" should be enough for me to get a basic understanding.
Thanks in advance.
Usually.. you don't call it "reference to an array of references of something" You just say "array of something". Even though arrays of objects are arrays of references to objects. Just like a variable for an object is just a reference to an object.
Type heyImAReference = new ImTheObject();
So when you write
Person person = new Person();
You'll have the class Person as type, person as a reference to an instance (or object) of that class and the resulting entity of new Person() as the actual thing that is being referenced. Usually called "instance" or in your case "object".
When it comes to arrays of persons and you do
Person[] persons = new Person[5];
You create via new Person[5] an array instance that has 5 slots, in each slot can go a Person instance figuratively, actually though you have 5 references. Person[0] being the first, Person[1] being the second and so on. So that is an "array of references to objects of class Person".
And persons is a reference to that. So it is a "reference to an array of references to objects of class Person"
static function getOldest taking the reference to an array of references to objects of class Person and returning the reference to the oldest person represented in the array
means nothing more than
static Person getOldest(Person[] persons) {
...
}
I would call that a method that takes an array of Persons and returns a Person. Though technically, it's all just references that go in and come out. The Person objects don't "move"
Firstly create another class which will have main method. Within main create an array:
Person[] parr = new Person[6];
//Then fill all your person to this array:
parr[0] = new Person("name", year);
parr[1] = ....
Then pass this array handler to your methods:
Person p1 = Person.findSomething(parr);
In Person class:
public static Person findSomething(Person[] parr){
for (Person p : parr){
if (p.name.endsWith("a")) return p;
}
return null;
}
Here are some hints which should help you work out the answer yourself without me giving away the solution ;)
1)
public static String getOlder(Person x?, Person y?) {
// if I understand the task correctly, I should reference any two names?
if(x?.yob>y?.yob) {
return x?.name;
} else {
return y?.name;
}
}
This code is almost correct! Just remove the question marks! Also remember that the older person will have an earlier yob. EDIT, also you need to return the reference to the person, not their name, so return either x or y.
2) getOldest and getYoungestWoman
Person[]
is an array of references to Person objects. You should be able to read up on how to loop through the elements of an array and compare values.
3) an extra: if you declare those 6 Person objects inside the constructor, you won't be able to access them in other methods of the class. it is ok to create the Person objects there, but you must declare them outside the constructor. Declare them in the class.
After searching I found these questions, but no answers to my specific question:
Undo/Redo with immutable objects
Why continue to use getters with immutable objects
How to write a test friendly immutable value class
Is it okay to expose the state of an immutable object
Here's the setup:
I've got an immutable class like so:
public class MyImmutableOb {
private final String name;
private final Collection<Integer> myNumbers;
public MyImmutableOb(String name) {
this.name = name;
myNumbers = new LinkedList<>();
}
public MyImmutableOb(String name, MyImmutableOb oldOb) {
this.name = name;
myNumbers = new LinkedList<>();
for (int i : oldOb.getNumbers()) myNumbers.add(i);
}
public Collection<Integer> getNumbers() {
return new LinkedList<>(myNumbers);
}
}
I have included a constructor like this, meant to allow simulating a name change on the object. The question is, does reproducing the Collection in this fashion break immutability?:
public MyImmutableOb(String name, MyImmutableOb oldOb) {
this.name = name;
myNumbers = new LinkedList<>();
for (int i : oldOb.getNumbers()) myNumbers.add(i);
}
I am having a tough time wrapping my head around this one.
As you have discovered, in order to make instances of your class immutable, you have to explicity write immutability into your class; object types (as opposed to primitive types) are mutable by nature. The collections classes in java.util are of course mutable. Java classes like String and the primitive boxing types Integer, Double, etc., are written to be immutable.
Your variable declaration
private final String name;
is immutable because it is declared final and because String objects are immutable.
Using the final keyword for a variable ensures that the variable can be assigned a value only once, therefore it is an excellent tool for designing an immutable class. However, it is not enough, because if the variable is assigned to a mutable object then the variables in that object can still be modified.
Your variable declaration
private final Collection<int> myNumbers;
does not guarantee immutability because, although myNumbers can be assigned only once, the collection assigned to it is still mutable.
The good news is, the Java Collections utility class provides lightweight wrappers to make your collections immutable. This will require a change to your first constructor
public MyImmutableOb(String name, int... numbers) {
this.name = name;
this.myNumbers = Collections.unmodifiableList(Arrays.asList(numbers));
}
so that myNumbers is now truly immutable. Note I've forsaken your usage of LinkedList, because there's no point in using that specialized List implementation when it's immutable within MyImmutableOb.
Thus your second constructor becomes
public MyImmutableOb(String name, MyImmutableOb oldOb) {
this.name = name;
this.myNumbers = oldOb.myNumbers;
}
because oldOb's myNumbers is already immutable, so there's no point in copying.
In closing, I realize you probably did want to be able to change the contents of myNumbers after construction of a MyImmutableOb. Obviously, making the class truly immutable implies that nothing can change in its instances after construction.
public static void main(String[] args)
{
String name = "john";
StringTest obj = new StringTest(name);
name = "peter";
System.out.println(obj.name);
}
}
class StringTest{
String name;
StringTest(String name)
{
this.name = name;
}
}
Now, since the string name has been reassigned from "john" to "peter" i expect it to print peter but it prints john. Has string being immutable causes a new object to be created when it is reassigned or what is the correct explanation for this?
Also when i try this with Integer object, the behaviour is same! Anyone please explain the reason for this behaviour
Java uses pass-by-value, which means that you pass the value of name, not the reference.
Changing the value of name after you already created the StringTest instance won't affect your StringTest in any way.
I think what throws you off here is the fact that you do not have to use the "new" keyword to create the strings. The code reads more like creating a primitive type like int or long instead of object creation. Which is what is actually taking place.
An equivalent way of creating the two strings is
String name = new String(new char[] {'j','o','h','n'});
StringTest obj = new StringTest(name);
name = new String(new char[] {'p','e','t','e','r'});
Written that way I think it is more clear why you do not achieve a side effect on the string referenced in StringTest. It has nothing to do with the fact that strings are indeed immutable.
What is the best way to store an element that has multiple elements? As in a 6d array.
I have seen something along the lines of ArrayList(ArrayList(ArrayList(ArrayList))), but don't have a clue as to how or mostly why it would be configure as such or how to access the elements!
As an example, I want to create an array(list) that stores the following information:
house id, house number, street name, residents, owner first name, owner last name
I would like to be able to sort and search on anyone of the sub-elements in the main record element.
What I have done is create an arraylist that contains an arraylist for each of these. Basically I have a class called HouseArray that has a method called CreateArray. From my class GUI, I have
houses = new HouseArray();
houses.CreateArray();
In class
HouseArray, my method CreateArray has
ArrayList<Integer> entryID;
ArrayList<Integer> houseNum;
ArrayList<String> streetName;
ArrayList<Integer> residents;
ArrayList<String> firstName;
ArrayList<String> lastName;
entryID = new ArrayList();
houseNum = new ArrayList();
streetName = new ArrayList();
residents = new ArrayList();
firstName = new ArrayList();
lastName = new ArrayList();
and then I use an AddEntry method that puts data into each arraylist.
this.entryID.add(12345);
this.houseNum.add(9876);
this.streetName.add("My Street");
this.residents.add(4);
this.firstName.add("John");
this.lastName.add("Jones");
I am at a loss at how I would be able to sort this mess and keep the entries synchronized without manually writing a lot of coding to do it all. Also, I want to be able to sum the number of residents that live on a particular streetName or total the number of residents that live in houses owned firstName or lastName.
Am I on the right track or is there a better way to do this?
Teaching myself java, so not sure if this counts as homework.
As an example, I want to create an array(list) that stores the
following information:
house id, house number, street name, house color, owner first name,
owner last name
the best approach is to create a Class name it House and have these attributes as its state.
class House {
private long houseId;
private long hNo;
private String streetname;
private String color;
private String owner;
private String firstName;
public House(long houseId, long hNo, String streetName, String color, String owner, String firstName){
//initialize your instance variables here
}
public void setHouseId(long houseId){
this.houseId = houseId;
}
//do the same thing for reamining attributes
//getters and setters for all the attributes.
}
now, create a java.util.List which holds House Object.
List<house> houseList = new Arraylist<>();
//and populate the list with house objects.
House house1 = new House(123,223,"Bond Street", "Green","James Bond", "James");
list.add(house1);
This approach is more Object-Oriented way of doing things, as House represents an Object which has state and behaviour.However, if you want to sort your House elements in your arrayList you will have to override equals and hashcode methods.
I think another approach would be create House class with those properties.
Instantiate house object and add to arraylist. You may override equals and hashcode method to perform sorting.
Example:
class House{
int houseNum;
String street;
...
//get/set for above properties.
}
And add it to list:
House houseObj = new House();
list.add(houseObj);
Where exactly have you seen along the lines of ArrayList(ArrayList(ArrayList(ArrayList)))?? This looks wierd. Never have such kind of design..
If you want to store multiple fields, then create a custom class with all those fields, and have an ArrayList of that class.
For e.g: -
class House{
private int houseId;
private int houseNumber;
private String streetName;
private String owner;
private String firstName;
// Constructors
// Getters and Setters
}
And create an ArrayList of that class: -
List<House> myHouses = new ArrayList<House>();
then, to add an object to your list, just use normal add method: -
myHouses.add(new House(houseId, houseNumber, ....));
And to access elements: -
for (House myHouse: myHouses) {
System.out.println(myHouse.getHouseNumber());
}
I think you're not just new to Java. You're new object-oriented programming in general. Are you a student and this is some sort of homework? If it is, please tag it as such.
For your particular data, your class should be House.
public class House
{
int entryId;
int houseNum;
String streetName;
String houseColor;
String firstName;
String lastName;
}
Note that in my sample code above, I'm assuming you know enough of java to add the access modifiers like private, public, etc. and know enough about how to add getter and setter methods, (e.g. getEntryId(), setEntryId(int entryId), etc.).
If your objects are actually more complex, you might also be better off creating classes like Address, Person, etc.
Then with this class, you do create a list:
List<House> houses = new ArrayList<House>();
House myHouse = new House();
// insert whatever data you want into "myHouse"
houses.add( myHouse );
To sort the objects in a list, because it's in a List, it's part of Java's Collection Framework. You can use the Collections.sort() method to sort it. But first you need to understand how it works.
I would suggest you the following pages:
Object-Oriented Programming Concepts
Java Tutorial: Collections
Object Ordering
I am at a loss at how I would be able to sort this mess
First, others have already pointed out that you should create a House class to organize "this mess".
To sort it, implement the Comparator interface, e.g. (assuming your House class has a getEntryID method):
public class HouseIDComparator implements Comparator<House> {
#Override
int compare(House house1, House house2) {
return house1.getEntryID().compareTo(house2.getEntryID());
}
}
This comparator can be passed to Collections.sort(List<T>, Comparator<? super T>) for sorting. (Note that there is also a sort method with one argument, for lists of types that implement the Comparable interface. However, you probably do not want your House class to implement that, since it is not obvious on what basis houses should be compared, and you yourself might want to use several different ones.)
As for summing up values, the best way is to loop over all elements in the list and sum up manually.