I want to try a simple implementation of phonebook with arraylist in java.
First I made a class contains what the info. needed and second I want have another class which have methods like getting info and printing them.
and because I want to use array list this is what I've done so far, but the 'print' method keep giving me the error in for loop, is there any one who can help me to optimize my code and why I have this error.
this is the first class :
public class PhoneBook {
long number;
String name;
.
.
.
.
getter() and setter();
}
The second class with methods:
public class PhoneBookMethods {
ArrayList<PhoneBook> phoneBooks = new ArrayList<PhoneBook>();
public void getInfo(PhoneBook phoneBooks)
{
.
.
.
}
public void print(PhoneBook phoneBooks)
{
for (PhoneBook p: phoneBooks) {// this is where I got the error
//foreach not applicable to type 'PhoneBook'
System.out.print(p.getName());
....
}
}
}
In your for-each loop, change
for (PhoneBook p: phoneBooks)
to
for (PhoneBook p: this.phoneBooks)
so that you would be accessing the phoneBooks arraylist, not the argument of the print method.
EDIT:
You can use the "this" keyword to make your code much more "explicit".
For the example, in your case you have an argument called phoneBooks that has the same name as your ArrayList (member variable). So to explicitly differentiate between the two of them, use this.phonebooks to access the member variable phoneBooks(the ArrayList), and use phoneBooks to refer to the argument.
If you want to use instance variable phoneBooks then no need to pass any param in the method print().
public void print()
{
for (PhoneBook p: phoneBooks) {// this is where I got the error
//foreach not applicable to type 'PhoneBook'
System.out.print(p.getName());
....
}
}
OR if you really want to pass param rename the param name
public void print(ArrayList<PhoneBook> phoneBookList)
{
for (PhoneBook p: phoneBookList) {// this is where I got the error
//foreach not applicable to type 'PhoneBook'
System.out.print(p.getName());
....
}
}
public void print(PhoneBook phoneBooks)
Your parameter phoneBooks masks the field (the array) also named phoneBooks. So compiler tries to treat parameter as list and failes.
Actually at first you have some design issues. The way you think what is a PhoneBook is invalid. You should consider a phonebook something holds several phones on it. Therefore, you may have a phone class like below:
public class Phone {
private String number;
private String name;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And a phonebook class responsible for holding those phone objects:
public class PhoneBook extends ArrayList<Phone> {
#Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for (Phone phone : this) {
stringBuilder.append("----------------------------\n");
stringBuilder.append("Name:" + phone.getName() + "\n");
stringBuilder.append("Number:" + phone.getNumber() + "\n");
}
return stringBuilder.toString();
}
}
It is a arraylist of Phone, nothing more. Thus, you can add or remove a phone directly via phone book. This is how to use it:
public class MAIN {
public static void main(String[] args) {
Phone myPhone = new Phone();
myPhone.setName("Eray");
myPhone.setNumber("0533XXXXXXX");
Phone girlfriendPhone = new Phone();
girlfriendPhone.setName("Canan");
girlfriendPhone.setNumber("0544XXXXXXX");
Phone yourPhone = new Phone();
yourPhone.setName("Bita Mirshafiee");
yourPhone.setNumber("0599XXXXXXX");
PhoneBook phoneBook = new PhoneBook();
phoneBook.add(myPhone);
phoneBook.add(girlfriendPhone);
phoneBook.add(yourPhone);
System.out.println(phoneBook);
}
}
Finally, this is the output:
----------------------------
Name:Eray
Number:0533XXXXXXX
----------------------------
Name:Canan
Number:0544XXXXXXX
----------------------------
Name:Bita Mirshafiee
Number:0599XXXXXXX
Related
We have to create a object of any class to use their funtionalities unless those are static functionalities. But why we dont need to create a ArrayList object to use its methods like add, contains etc..
ArrayList<Egg> myList = new ArrayList<Egg>();
myList.add(a);
According to my understanding, myList is just variable which holds ArrayList object's reference of type ArrayList class. So again how can we write following without passing object to myList.
ArrayList<Egg> myList;
myList.add(a);
Complete code:
import java.util.ArrayList;
public class DotCom {
private ArrayList<String> locationCells;
public void setLocationCells(ArrayList<String> loc)
{
locationCells = loc;
}
public String checkYourself(String userInput)
{
String result = "miss";
int index = locationCells.indexOf(userInput);
if (index >= 0) {
locationCells.remove(index);
if (locationCells.isEmpty()) {
result = "kill";
}
else
{
result = "hit";
}
}
return result;
}
//TODO: all the following code was added and should have been included in the book
private String name;
public void setName(String string) {
name = string;
}
}
PS
I am referring heads first java book.
The ArrayList reference is being set in the setter method:
public void setLocationCells(ArrayList<String> loc)
{
locationCells = loc;
}
If this method is not called, and the reference not set before trying to use the ArrayList, then the code will throw a NullPointerException.
Side note: This does not look to be safe code, since it can be easily run incorrectly and so a NPE is easy to create. Better perhaps to set the ArrayList (List is even better) in a constructor.
This has been bugging me for a while. I am new to serious OOps concepts and came across. Here's what I have:
Class ape:
public class ape {
String name;
public String getBehavior() {
return "I am apeshit";
}
}
Class humano:
public class humano extends ape {
public String name;
public humano(String namevalue) {
name = namevalue;
}
public String getBehavior() {
return "I am a :" + name;
}
public String getName() {
return name;
}
}
Class neandarthal:
public class neandarthal extends ape {
String name;
public neandarthal(String name) {
super.name = name;
}
public String getBehavior() {
return "I am a :" + name;
}
public String getName() {
return name;
}
}
Species_Factory Class:
public class species_factory {
static ape ap = null;
static ape getSpecies(String name) {
if (name == "humano") {
return new humano(name);
}
if (name == "neandarthal") {
return new neandarthal(name);
}
else {
return ap;
}
}
}
And Finally the main class species:
public class species {
public static void main(String args[]) {
ape a1 = species_factory.getSpecies("humano");
ape a2 = species_factory.getSpecies("neandarthal");
System.out.println(a1.name);
System.out.println(a2.name);
System.out.println(a1.getBehavior());
System.out.println(a2.getBehavior());
System.out.println(a1.getClass().getSuperclass().getName());
}
}
The output:
null
neandarthal
I am a :humano
I am a :null
ape
The query I have is regarding the null value. Basically when I try to display System.out.println(a1.name). I am seeing null. Why is this?
I see that I am getting the value I am a :humano in the third line, which means that the value I pass for the string variable name is getting stored in the humano instance.
But why is it not displayed when I try to display the same variable using the statement System.out.println(a1.name)?
Sorry might be a silly question with my lack of understanding..but will be very grateful for a reply.
Basically when I try to display "System.out.println(a1.name)" I am seeing null. Why is this?
The main problem here is that by redeclaring name in humano and neandarthal, you're shadowing the name field that exists in ape. That means that the objects created by humano and neandarthal have two name fields: The one defined by ape, and a separate one they define for themselves. Then in the code, you're being very inconsistent about which name field you use.
You almost certainly want to remove the name declarations in humano and neandarthal (and then use this., not super., on name), so you're using the field declared in ape.
The specific reasons for what you're seeing are:
The first line ("null"): humano assigns to its own name field, but when you use a1.name in your main, since a1 is declared as an ape, it's using the namefield in ape (which is still null, nothing has ever assigned to it).
The second line ("neandarthal"): neandarthal assigns to ape's name field (super.name = ...), not its own. Since a2 is declared as ape, a2.ape uses that and you see the string you assigned.
The third line ("I am a :humano"): humano's getBehavior uses its own name field, not ape's, so you see what the constructor assigned to it.
The fourth line ("I am a :null"): neandarthal's getBehavior uses its own name field, which is still null because nothing has ever assigned to it).
The fifth line ("ape"): I don't think you're confused about this, but humano's superclass is ape.
The pet store program should start with the user being able to choose to adopt a pet or give a pet the to the shop. If the user wants to adopt a pet, they should be able to see either all available pets, unless they say they know what type of pet they want, then show only available pets of that type.
The 4 methods that will need to be created for this program should:
add new pets
get a pet adopted
show pets by type
show pets available for adoption
Object Class: Pets.java
import java.util.*;
public class Pets {
public static void main(String[] args){
private double age; // age of the animal (e.g. for 6 months the age would be .5)
private String petName; // name of the animal
private String aType; // the type of the pet (e.g. "bird", "dog", "cat", "fish", etc)
private int collarID; // id number for the pets
private boolean isAdopted = false; // truth of if the pet has been adopted or not
private String newOwner;
private Date adoptionDate;
public double getAge() {
return age;
}
public void setAge(double age) {
this.age = age;
}
public String getPetName() {
return petName;
}
public void setPetName(String petName) {
this.petName = petName;
}
public String getaType() {
return aType;
}
public void setaType(String aType) {
this.aType = aType;
}
public int getCollarId() {
return collarID;
}
public void setCollarId(int collarId) {
this.collarID = collarId;
}
public boolean isAdoptated() {
return isAdopted;
}
public void setAdoptated(boolean isAdoptated) {
this.isAdopted = isAdoptated;
}
public Date getAdoptionDate() {
return adoptionDate;
}
public void setAdoptionDate(Date adoptionDate) {
this.adoptionDate = adoptionDate;
}
#Override
public String toString() {
return "Pets [age=" + age + ", petName=" + petName + ", aType=" + aType + ", collarId=" + collarID
+ ", isAdoptated=" + isAdopted + ", adoptionDate=" + adoptionDate + "]";
}
}
}
You should define the data fields and methods inside the class, but not inside the main()-method. The main()-method is the entry point of your java application and could be used to create an instance of your Pets class.
e.g.:
public static void main(String[] args) {
Pets pet = new Pets();
}
This code is not compiling for 2 main reasons:
You are specifying access modifiers on variables inside a method (in this case main), which is forbidden;
You are writing methods (e.g. getAge) inside another method (main) and trying to return a variable (e.g. age) that is out of that scope, in fact the variable age is not known inside the getAge method, because it's declared in the main method.
You should move the variable declaration to class level, and then have all methods separated using those variables. I'll give you a sketch, not the complete solution:
import java.util.*;
public class Pets {
/* Insert all variable declarations here */
private double age;
/* Constructor if you need it */
public Pets(/* parameters you think you need */) {
// Set attributes when you declare a new Pets()
}
/* Insert all methods you need here */
public double getAge() {
return this.age;
}
The positioning of the main method - for what I've understoon from your description - should be placed outside this class, in another class where the whole application will start to run. The Pet class should serve only for anything concerning pets (the four methods you will need to implement and all getters/setters for retrieving private class variables).
You’ve happened to put about everything — private fields and public methods — inside you main method. That doesn’t make sense. Everything that is in your main, move it outside, right under the line public class Pets {. That should fix your compiler error.
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 9 years ago.
I am having an issue with this error, while trying to write a method that lists all names in a specific class. (error at bottom) I have tried a few things but for the life of me, cannot figure it out. Please help, thanks.
Class Cat:
public class Cat
{
// instance variables
private String name;
private int yearOfBirth;
private int weightInKilos;
public Cat() {
setName("");
setYearOfBirth(0);
setWeightInKilos(0);
}
/**
*
*/
public Cat(String newName, int newYearOfBirth, int newWieghtInKilos )
{
setName(newName);
setYearOfBirth(newYearOfBirth);
setWeightInKilos(newWieghtInKilos);
}
public String getName(){
return name;
}
public int getYearOfBirth(){
return yearOfBirth;
}
public int getWieghtInKilos(){
return weightInKilos;
}
public void setName(String newName){
if (newName != null ){
name = newName;
}
else{
System.out.println("Invalid Name");
}
}
public void setYearOfBirth(int newYearOfBirth){
if (yearOfBirth >= 0){
yearOfBirth = newYearOfBirth;
}
else{
System.out.println("Year Of Birth must not be negative!");
}
}
public void setWeightInKilos(int newWeightInKilos){
if (weightInKilos >= 0){
weightInKilos = newWeightInKilos;
}
else{
System.out.println("Weight must not be negative!");
}
}
}
Class Cattery:
import java.util.ArrayList;
public class Cattery
{
// instance variables - replace the example below with your own
private ArrayList <Cat> cats;
private String businessName;
/**
* Constructor for objects of class Cattery
*/
public Cattery(String NewBusinessName)
{
cats = new ArrayList <Cat>();
NewBusinessName = businessName;
}
public void addCat(Cat newCat){
cats.add(newCat);
}
public void indexDisplay(int index) {
if((index >= 0) && (index <= cats.size()-1)) {
System.out.println(index);
}
else{
System.out.println("Invalid index position!");
}
}
public void removeCat(int indexremove){
if((indexremove >= 0) && (indexremove <= cats.size()-1)) {
cats.remove(indexremove);
}
else{
System.out.println("Invalid index position!");
}
}
public void displayNames(){
System.out.println("The current guests in Puss in Boots Cattery:");
for(Cat catNames : cats ){
System.out.println(Cat.getName()); //ERROR; non static method cannot be referenced from a static context..wtf
}
}
}
Please help, thanks
When you have an instance method, you need to call it on a specific instance of the class.
Here:
System.out.println(Cat.getName());
you're trying to call it on the Cat class itself. You want:
for (Cat cat : cats ) {
System.out.println(cat.getName());
}
Note that I've changed the name of the iteration variable from catNames to cat as well - because the value is just a reference to "the cat we're looking at at the moment". It's not the cat name, nor is it multiple cats (or cats names) - it's a single cat. It's very important to name variables carefully - it can help correct code to look correct, and incorrect code to look incorrect. It doesn't make sense to call getName() on a variable called catNames... (what is the name of a collection of names?) but it absolutely makes sense to call it on a variable called cat.
Another warning bell from your original code was that the body of your for loop didn't use the iteration variable - that almost always suggests that something's wrong. The fixed version does, of course.
Use:
System.out.println(catNames.getName());
getName is non static function, so you need to use it on an instance of that class, like you have in the cats list.
Cat.getName() this line means getName() should be static method in Cat class, but's not as such.
so access getName() method by instacne .
System.out.println(catNames.getName());
for (Cat cat : cats) {
System.out.println(Cat.getName());
}
Here you need to use cat, not Cat. So use
for (Cat cat : cats) {
System.out.println(cat.getName());
}
I am a beginner programmer and this is my first question on this forum.
I am writing a simple text adventure game using BlueJ as a compiler, and I am on a Mac. The problem I ran into is that I would like to make my code more self automated, but I cannot call a class with a string. The reason I want call the class and not have it all in an if function is so that I may incorporate more methods.
Here is how it will run currently:
public class textadventure {
public method(String room){
if(room==street){street.enterRoom();}
}
}
public class street{
public enterRoom(){
//do stuff and call other methods
}
}
The if statement tests for every class/room I create. What I would like the code to do is automatically make the string room into a class name that can be called. So it may act like so:
Public method(string room){
Class Room = room;
Room.enterRoom();
}
I have already looked into using Class.forName, but all the examples were too general for me to understand how to use the function. Any help would be greatly appreciated, and if there is any other necessary information (such as more example code) I am happy to provide it.
-Sebastien
Here is the full code:
import java.awt.*;
import javax.swing.*;
public class Player extends JApplet{
public String textOnScreen;
public void start(){
room("street1");
}
public void room(String room){
if(room=="street1"){
textOnScreen=street1.enterRoom();
repaint();
}
if(room=="street2"){
textOnScreen=street2.enterRoom();
repaint();
}
}
public void paint(Graphics g){
g.drawString(textOnScreen,5,15);
}
}
public abstract class street1
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on a street running from North to South.";
return textToScreen;
}
}
public abstract class street2
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on another street.";
return textToScreen;
}
}
Seeing as you are rather new to programming, I would recommend starting with some programs that are simpler than a full-fledged adventure game. You still haven't fully grasped some of the fundamentals of the Java syntax. Take, for example, the HelloWorld program:
public class HelloWorld {
public static void main(String[] args) {
String output = "Hello World!"
System.out.println(output);
}
}
Notice that public is lowercased. Public with a capital P is not the same as public.
Also notice that the String class has a capital S.* Again, capitalization matters, so string is not the same as String.
In addition, note that I didn't have to use String string = new String("string"). You can use String string = "string". This syntax runs faster and is easier to read.
When testing for string equality, you need to use String.equals instead of ==. This is because a == b checks for object equality (i.e. a and b occupy the same spot in memory) and stringOne.equals(stringTwo) checks to see if stringOne has the same characters in the same order as stringTwo regardless of where they are in memory.
Now, as for your question, I would recommend using either an Enum or a Map to keep track of which object to use.
For example:
public class Tester {
public enum Location {
ROOM_A("Room A", "You are going into Room A"),
ROOM_B("Room B", "You are going into Room B"),
OUTSIDE("Outside", "You are going outside");
private final String name;
private final String actionText;
private Location(String name, String actionText) {
this.name = name;
this.actionText = actionText;
}
public String getActionText() {
return this.actionText;
}
public String getName() {
return this.name;
}
public static Location findByName(String name) {
name = name.toUpperCase().replaceAll("\\s+", "_");
try {
return Enum.valueOf(Location.class, name);
} catch (IllegalArgumentException e) {
return null;
}
}
}
private Location currentLocation;
public void changeLocation(String locationName) {
Location location = Location.findByName(locationName);
if (location == null) {
System.out.println("Unknown room: " + locationName);
} else if (currentLocation != null && currentLocation.equals(location)) {
System.out.println("Already in room " + location.getName());
} else {
System.out.println(location.getActionText());
currentLocation = location;
}
}
public static void main(String[] args) {
Tester tester = new Tester();
tester.changeLocation("room a");
tester.changeLocation("room b");
tester.changeLocation("room c");
tester.changeLocation("room b");
tester.changeLocation("outside");
}
}
*This is the standard way of formating Java code. Class names are PascalCased while variable names are camelCased.
String className=getClassName();//Get class name from user here
String fnName=getMethodName();//Get function name from user here
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(className);// get the Class
Object inst = thisClass.newInstance();// get an instance
// get the method
Method fn = thisClass.getDeclaredMethod(fnName, params);
// call the method
fn.invoke(inst, paramsObj);
The comments below your question are true - your code is very rough.
Anyway, if you have a method like
public void doSomething(String str) {
if (str.equals("whatever")) {
// do something
}
}
Then call it like
doSomething("whatever");
In Java, many classes have attributes, and you can and will often have multiple instances from the same class.
How would you identify which is which by name?
For example
class Room {
List<Monster> monsters = new ArrayList <Monster> ();
public Room (int monstercount) {
for (int i = 0; i < monstercount; ++i)
monsters.add (new Monster ());
}
// ...
}
Monsters can have attributes, and if one of them is dead, you can identify it more easily if you don't handle everything in Strings.