Array of custom Java objects - java

I am trying to create an array of Person (a class that with variables String name, and double total). But for some reason, creating a second Person replaces(?) the first person. . .
Person[] p = new Person[40];
p[0] = new Person("Jango", 32);
p[1] = new Person("Grace", 455);
System.out.println( p[0].getName() );
System.out.println( p[1].getName() );
System.out.println( p[0].equals(p[1]) );
The output is:
Grace
Grace
false
Why isn't it:
Jango
Grace
false
????????????
public class Person {
#SuppressWarnings("unused")
private Person next;
private String name;
private double total;
public Person(String _name)
{
name = _name;
total = 0.0;
next = null;
}
public Person(String _name, double _total)
{
name = _name;
total = _total;
next = null;
}
public String getName()
{
return name;
}
}

Your problem is that the name instance variable is declared as static, making it a class variable. Any change to name will be changed for every instance of that class.. You need to remove the static identifier from name and from total and your code will work fine.

Currently these variables are static which means that they they will retain the last values assigned.
private static String name;
private static double total;
You need to make these fields class instance variables:
private String name;
private double total;
See Understanding Instance and Class Members

Your fields are static. They should not be, if you want them to be able to store a separate instance of a name and total for each instance of the class.

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 :)

Registering object field values Java

I've recently started programming with Java and I like to know if there is a way to register(like put in array or something) certain object field values.
In this case, for example all "name" values(private final String name) of created objects.
Any help would be greatly appreciated.
public class Item {
private int amount;
private double price;
private final String name;
private final String type;
private final String madeIn;
Item(int amount, double price, String name, String type, String madeIn){
this.amount=amount;
this.madeIn=madeIn;
this.name=name;
this.type=type;
this.price=price;
}
You have many data structures in Java in the Collection family like List or Set. You also have associative (key/value) collections with Map and its sub-classes.
Trying to read between the lines in your question, you may want to have some collection of Items that you want to access through there name field.
Assuming the name is unique in an Item and you have getters for the properties:
Map<String, Item> itemsByName = new HashMap<>();
// put some items...
itemsByName.put(item1.getName(), item1);
itemsByName.put(item2.getName(), item2);
// etc...
// Looking for an item knowing its name
String key = "Foo";
Item itemFound = itemsByName.get(key);
if (itemFound==null) {
System.out.println("There is no item whose name is " + key);
}
else {
// do something with itemFound
}
There's nothing stopping you from adding some static Set member to your class that would contain all the names of the created instances.
Inside the Item constructor you can add name to this Set.
public class Item {
private int amount;
private double price;
private final String name;
private final String type;
private final String madeIn;
private static Set<String> registeredNames = new HashSet<String>();
Item(int amount, double price, String name, String type, String madeIn)
{
registeredNames.add (name); // you should consider what you want to do
// if the same name is passed to two instances
// perhaps throw an exception
this.amount=amount;
this.madeIn=madeIn;
this.name=name;
this.type=type;
this.price=price;
}
}
Just create a static List of names and keep on adding that in the constructor like:
private final static List<String> names = new LinkedList<String>();
public Item(..) {
names.add(name);
}

calling a function containg enum in java

I have defined a class
class Prop{
public static enum property{
NAME,
CITY,
ADDRESS;
}
private String NAME;
private String CITY;
private String ADDRESS;
public String getValue(property pro){
switch(pro){
case NAME:
return NAME;
case CITY:
return CITY;}
return null;}
}
class CallPro{
private String name;
name=Prop.getValue("");
}
I am not exactly getting how to call getValue from class CallPro.
Basically what parameters should be passed to get the desired value.
I am a beginner in java
To run this program you need a public static void main(String[]) method first. That's your entry point into any Java program. Since, you want to assign the values inside callPro, add the main() method there.
Next, you want to call getProperty() which is an instance method belonging to class prop, so you'll need to create an instance of it first using the new constructor() syntax.
class callPro {
private static String name;
private static String city;
private static String address;
public static void main(String[] args) {
// create prop instance
prop property = new prop();
// call prop's method getValue()
name = property.getValue(prop.property.CITY);
city = property.getValue(prop.property.NAME);
address = property.getValue(prop.property.ADDRESS);
// New York, John, Central Park
System.out.println(name + ", " + city + ", " + address);
}
}
Notice, how I had to make callPro's members static to be able to access them inside the main() method because that's static too. Also, note how I referenced the Enums: className.enumType.enumValue.
To be able to see the values print from the main() method, you'll also need to provide values for your prop class members as
private String NAME = "John";
private String CITY = "New York";
private String ADDRESS = "Central Park";
public String getValue(property pro) {
switch (pro) {
case NAME:
return NAME;
case CITY:
return CITY;
case ADDRESS:
return ADDRESS;
}
return null;
}
Yes, you can loop through an enum's values and retrieve your properties in a loop as
prop property = new prop();
for (prop.property prop : prop.property.values()) {
System.out.println(property.getValue(prop));
}
enumType.values() returns an enumType[] of all enumValues which can be used with a for-each loop as shown above.

please help me with self-reference pointer

i have written two classes first one Member and second one Store. and i wrote a method which can create an object from the member class and i am trying to to write a field store of type Store in the Member class and i want it store a reference to the store the member has entered.
some told me to do this :
memberRegister() needs to be passed, as an argument, a pointer to the Store object that you are currently in.
In fact, the Store object needs to be able to tell the Member object "point to me". That is, the Store object needs a pointer to itself.
but i did not get it
this is Member class
private int pinNumber;
private String name, id;
private Store store;
/**
* Constructor for objects of class Member
*/
public Member(String name, String id, int pinNumber, Store store)
{
// initialise instance variables
this.name = name;
this.id = id;
this.pinNumber = pinNumber;
checkId();
checkPinNumber();
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
private void checkId()
{
// put your code here
int length;
length = id.length();
if (length > 10 ){
System.out.println("lentgh must be at 10 ");
}
}
private void checkPinNumber()
{
int length;
length = id.length();
if ((length > 4) && (length < 4 )){
System.out.println("lentgh must be at 4");
}
class store
private String storeName;
private int total;
private Member member;
/**
* Constructor for objects of class Store
*/
public Store(String storeName, int total)
{
// initialise instance variables
this.storeName = storeName;
this.total = total;
}
/**
*
*/
public String getStoreName()
{
return storeName;
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public Member memberRegister(String name, String id, int pinNumber)
{
// put your code here
Member member;
member = new Member(name, id, pinNumber)
return member;
}
your memberRegister method doesn't invoke your Member constructor correctly:
public Member memberRegister(String name, String id, int pinNumber)
{
// put your code here
Member member;
member = new Member(name, id, pinNumber, this) //this passes in a reference to your store
return member;
}
Then you assign the reference in your Member constructor:
public Member(String name, String id, int pinNumber, Store store)
{
// initialise instance variables
this.name = name;
this.id = id;
this.store = store //where this.store is a Store
this.pinNumber = pinNumber;
checkId();
checkPinNumber();
}
Hope that helps. By the way, update the comments in a way, that they match your code.
Using the keyword this is how you are able to get a self-referential pointer. You should be able to do as #Kerrek SB suggested and return new Member(name, id, pinNumber, this) from inside the memberRegister method.
See in your case passing this keyword to method memberRegister is useless
returning this keyword is useful.
to know more about this keyword check this

Initialize final variable before constructor in Java

Is there a solution to use a final variable in a Java constructor?
The problem is that if I initialize a final field like:
private final String name = "a name";
then I cannot use it in the constructor. Java first runs the constructor and then the fields. Is there a solution that allows me to access the final field in the constructor?
I do not really understand your question. That
public class Test3 {
private final String test = "test123";
public Test3() {
System.out.println("Test = "+test);
}
public static void main(String[] args) {
Test3 t = new Test3();
}
}
executes as follows:
$ javac Test3.java && java Test3
Test = test123
Do the initialization in the constructor, e.g.,
private final String name;
private YourObj() {
name = "a name";
}
Of course, if you actually know the value at variable declaration time, it makes more sense to make it a constant, e.g.,
private static final String NAME = "a name";
We're getting away from the question.
Yes, you can use a private final variable. For example:
public class Account {
private final String accountNumber;
private final String routingNumber;
public Account(String accountNumber, String routingNumber) {
this.accountNumber = accountNumber;
this.routingNumber = routingNumber;
}
}
What this means is that the Account class has a dependency on the two Strings, account and routing numbers. The values of these class attributes MUST be set when the Account class is constructed, and these number cannot be changed without creating a new class.
The 'final' modifier here makes the attributes immutable.
Marking it static, will allow you to use it in the constructor, but since you made it final, it can not be changed.
private static final String name = "a_name";
is is possible to use a static init block as well.
private static final String name;
static { name = "a_name"; }
If you are trying to modify the value in the constructor, then you can't assign a default value or you have to make it not final.
private String name = "a_name";
Foo( String name )
{
this.name = name;
}
or
private final String name;
Foo( String name )
{
if( s == null )
this.name = "a_name";
else
this.name = name;
}
In this case, you can mark the field as 'static' also.
Another possiblity is to initialize the field in an instance initializer blocK:
public class Foo {
final String bar;
{
System.out.println("initializing bar");
bar = "created at " + System.currentTimeMillis();
}
public Foo() {
System.out.println("in constructor. bar=" + bar);
}
public static void main(String[] args) {
new Foo();
}
}
In that case, you might as well make it static, too. And Java convention is to name such constants in ALL_CAPS.
private static final String name = getName();
where getName() is a static function that gets you the name.
I cannot use it in the constructor, while java first runs the constructor an then the fields...
This is not correct, fields are evaluated first, otherwise you couldn't access any default values of members in your constructors, since they would not be initialized. This does work:
public class A {
protected int member = 1;
public A() {
System.out.println(member);
}
}
The keyword final merely marks the member constant, it is treated as any other member otherwise.
EDIT: Are you trying to set the value in the constructor? That wouldn't work, since the member is immutable if defined as final.

Categories