I'm writting a simple model of a social media where a users friends is represented as an array of Friend objects.
I am getting the titled error with the use of the method toStringFriends used in the main method. Doe anyone know how to fix this problem?
public class Friend {
private String name;
private String password;
private int uid;
private Friend [] friends;
public Friend (String name, String password, int uid, Friend [] friends) {
this.name = name;
this.password = password;
this.uid = uid;
this.friends [0] = friends [0];
}
public Friend [] getFriends () {
return friends;
}
public String toStringFriends (Friend [] friends) {
String s = "";
for (int i = 0; i <= friends.length; i++) {
s = s + (friends [i]).getName();
}
return s;
}
}
public class Main {
public static void main(String[] args) {
Friend [] noFriends = new Friend [0];
Friend [] laurasFriends = new Friend [1];
Friend jack = new Friend ("jack","liverpool",1,noFriends);
laurasFriends [0] = jack;
Friend laura = new Friend ("laura","everton",2,laurasFriends);
String s = toStringFriends(laurasFriends);
System.out.println(s);
System.out.println(toStringFriends(laura.getFriends()));
}
}
You need to call it from laura's instance of the object:
String s = laura.toStringFriends(laurasFriends);
toStringFriends has access to friends and name so I would pass a separator if I passed anything. I would also prefer a StringBuilder to using String concatenation in a loop. And I don't see a getName() in your class, but Friend has access to its' own data. Then <= is going to cause an array index out of bounds exception, because valid array indices are 0 to friends.length - 1. So you can do something like,
public String toStringFriends(String sep) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < friends.length; i++) {
if (i != 0) {
sb.append(sep);
}
sb.append(friends[i].name);
}
return sb.toString();
}
And then change this.friends [0] = friends [0]; to this.friends = friends; in your constructor, and finally call toStringFriends like
String s = laura.toStringFriends(",");
Use it by creating Friend class object-
Friend friend=new Friend(<constructor input
parameters>);
friend.toStringFriends(<function input
parameters>);
Or make toStringFriends() static and call it by using Friend class.
You can't call an instance or non static method without object. You should use some instance object and then you can call via . operator.
Like object.method()
Either make toStringFriends() static or instantiate a Friend object and call that method on it.
Related
Not able to print the toString method, would like to be able to print the accessor and am not sure what the issue is. Am I not storing the array as an instance properly? I'd like to access the array in future methods so it is important for it to be stored as an instance.
public class j {
private double[] s;
public j() throws FileNotFoundException {
File in = new File("file.txt");
Scanner inScanFile = new Scanner(in);
int lines = inScanFile.nextInt();
s = new double[lines];
}
public double getXintercept(){
return s[2];
}
public String toString() {
double c = getXintercept();
System.out.println(c);
String descrip = "";
descrip = "kiki" + c; //want this to display and it won't
return descrip;
}
}
Create the object of this class in main method and then print the object using
System.out.println(yourobject);
Disclaimer: I just learnt how to do this yesterday, and I am desperate
I have 3 classes (Student, ClassSchedule, ClassEnrolment)
public class ClassEnrolment {
ClassSchedule cs;
Student stud;
public ClassEnrolment(ClassSchedule cs, Student stud) {
super();
this.cs = cs;
this.stud = stud;
}
}
-----
public class Student{
private String name;
private String matricNo;
ClassEnrolment classroom;
ClassSchedule schedule;
}
-----
public class ClassSchedule {
String classType;
int index;
int group;
String day;
String time;
String venue;
String remark;
String courseCode;
}
I am trying to read/write a text file (database). I am having issues with 3 lines inside "/////////////////".
I am aware that the attributes declared in ClassEnrolment are not int nor string. How should I do this? How do I bring ClassSchedule and Student as part of StringTokenizer?
The textfile stores index from ClassSchedule and matricNo from Student. I have a feeling I am doing this wrongly.
public static ArrayList readEnrolment(String filename) throws IOException {
ArrayList stringArray = (ArrayList) read(filename);
ArrayList alr = new ArrayList();
for (int i = 0; i < stringArray.size(); i++) {
String st = (String) stringArray.get(i);
StringTokenizer star = new StringTokenizer(st, SEPARATOR);
///////////////////////////////////////////////////
int cs = Integer.parseInt(star.nextToken().trim());
String stud = star.nextToken().trim();
ClassEnrolment enrolment = new ClassEnrolment(cs, stud);
//////////////////////////////////////////////////
alr.add(enrolment);
}
return alr;
}
public static void saveEnrolment(String filename, List al) throws IOException {
List alw = new ArrayList();
for (int i = 0; i < al.size(); i++) {
ClassEnrolment enrolment = (ClassEnrolment) al.get(i);
StringBuilder st = new StringBuilder();
st.append(enrolment.getCs2());
st.append(SEPARATOR);
st.append(enrolment.getStud2());
alw.add(st.toString());
}
write(filename, alw);
}
Your problem here is an issue of Serialization. You could very well declare your classEnrolment as Serializable(do not forget the serialUUID) and let the classic java serialization process to write your objects as bytes in your file.
However, what you are trying here is to conceive a custom serializer for your class. I'd advise you to use generics in the likes of :
public interface Serializer<T> {
byte[] write(T objectToSerialize);
//to build a factory/service around it
boolean canDeserialize(byte[] serializedObject);
T read(byte[] serializedObject);
}
So that your methods read/writeEnrollment will simply be creating a Serializer<ClassEnrollment> and letting it do its job (which will probably create a Serializer<Student> and a Serializer<ClassSchedule>) .
For the matter of the Serialization process, I have to say that the StringTokenizer is a legacy class from JDK 1 whose use is discouraged by its own javadoc :
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
And if you want to Serialize objects of potentially different classes than just your ClassEnrollment, it would be nice to be able to distinguish the class used. There are many ways to do it, and as one commenter said, json serialization would fare very well.
I am having issues with objects and classes.
I had to define two classes:
Course: a course has a code, an name and a number of credits
Teacher: a teacher has a first name and last name. He can be asked his full name.
So far so good, I got no issue with them, but I have to do next assignment which I was trying to do in the last 2 days and I could not find a proper answer:
Extend the code of the class teacher. A teacher also has a list of courses he can teach. Add an array of Courses to the code. Also add a function addCourse(Course aCourse) to the code. Courses can also be removed from teachers.
I could do everyting in my way but no clue on how to create the addCourse(Course aCourse) method.
Find below my coding, but it must be according to the method described:
public class Course {
private String courseCode;
private String courseName;
private String numberOfCredits;
public Course(String courseCode, String courseName, String numberOfCredits) {
super();
this.courseCode = courseCode;
this.courseName = courseName;
this.numberOfCredits = numberOfCredits;
}
public void print() {
System.out.println(courseCode + "\t" + courseName + "\t" + numberOfCredits);
}
public static void main(String[] args) {
Course[] courseArray = new Course[4];
System.out.println("Code" + "\t" + "Name" + "\t" + "Credits");
courseArray[0] = new Course("001", "Hist", "3");
courseArray[1] = new Course("002", "Phy", "3");
courseArray[2] = new Course("003", "Math", "3");
courseArray[3] = new Course("004", "Log", "3");
for (int i = 0; i < courseArray.length; i++) {
courseArray[i].print();
}
}
}
Arrays are fixed length collections of objects, so you'll need to decide how big your array should be. Let's call the length of your array MAX_COURSES. A more advanced solution might resize the array when required, but I get the impression this is beyond the scope of your course.
So you need to define the Course[] array as a field of your Teacher class. The syntax of array declarations is quite easy to research, so I won't put that in here. Just make sure your array length is equal to MAX_COURSES.
Now, to add courses to the array, you need to know where to put them. To keep track of the next free position of the array, the easiest thing to do is to declare a field in your class:
private int numCourses = 0;
Now, when you add a new course, insert the course into the index specified by numCourses. Make sure you increment numCourses after you've added the course.
Finally, you ought to test to see if your array is full before you agree to insert a new course into the array, i.e. check if numCourses is smaller than MAX_COURSES. If it's not, you need to throw an exception.
I would recommend using a collection (such as a List) rather than an array. The code would look something like:
public class Teacher {
private final String firstName;
private final String lastName;
private final List<Course> courses = new ArrayList<Course>();
public Teacher(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public void addCourse(Course course) {
courses.add(course);
}
}
Based on that example, you should be able to add the removeCourse method yourself, and any other method you need to operate on the list of courses.
If you want to return the list as an array, you could always convert it, e.g:
public Course[] getCourses() {
return courses.toArray(new Course[courses.size()]);
}
If you really need to use an array for the data structure based on your assignment, something you can try when adding and removing courses, is to construct a list from the array of courses, add or remove a course from that list, the convert the list back to an array of courses.
There's really 3 options here.
Option 1
If you're allowed to use List constructs:
private List<Course> courses = new ArrayList<Course>();
public void addCourse(Course aCourse)
{
if (aCourse == null)
{
return;
}
courses.add(aCourse);
}
Option 2
The uses arrays, but it doesn't scale. Assume that a teacher can only have a maximum of X courses, in my example 10:
// Yes, I stole Duncan's variable names
private final int MAX_COURSES = 10;
private int numCourses = 0;
private Course[] courses = new Course[MAX_COURSES];
public void addCourse(Course aCourse) {
if (aCourse == null)
{
return;
}
if (numCourses >= courses.length)
{
return;
}
courses[numCourses] = aCourse;
numCourses++;
}
Option 3
This is identical to the previous item, but is a bit smarter in that it can resize the array... by creating a new one using the static method Arrays.copyOf
// Yes, I stole Duncan's variable names
private final int MAX_COURSES = 10;
private int numCourses = 0;
private Course[] courses = new Course[MAX_COURSES];
public void addCourse(Course aCourse) {
if (aCourse == null)
{
return;
}
if (numCourses >= courses.length)
{
int size = courses.length * 2;
courses = Arrays.copyOf(courses, size);
}
courses[numCourses] = aCourse;
numCourses++;
}
public class TestClass extends BaseClass {
public void getquote() {
String FirstName = "Sam";
String LastName = "Gayle";
String Email = "somename#somename.com";
String Password = "test1234";
CallGetQuote(FirstName, LastName, Email, Password);
}
private void CallGetQuote(String... var) {
for (int i = 0; i < var.length; i++) {
driver.findElement(By.id("first-name")).sendKeys(var[i]);
driver.findElement(By.id("last-name")).sendKeys(var[i]);
driver.findElement(By.id("join-email")).sendKeys(var[i]);
driver.findElement(By.id("join-password")).sendKeys(var[i]);
// driver.findElement(By.name("btn-submit")).click();
}
}
}
`I would like to fill in the objects using a loop rather than hard coded index number as mentioned. Above is what I wrote, at the moment, all text boxes are filling with all values. Please help :(
Thanks.`
You can use varargs, more informations could be found in the JLS:
You can use a construct called varargs to pass an arbitrary number of
values to a method. You use varargs when you don't know how many of a
particular type of argument will be passed to the method.
So, your code will be something like:
public void getquote() {
String firstName = "Sam";
String lastName = "Gayle";
String email = "somename#somename.com";
String password = "test1234";
CallGetQuote(FirstName, LastName, Email, Password);
}
public void CallGetQuote(String... var) {
// add your elements to a List
List<MyElements> inputElements = new ArrayList<MyElements>;
inputElements.add(driver.findElement(By.id("first-name")));
inputElements.add(driver.findElement(By.id("last-name")));
inputElements.add(driver.findElement(By.id("join-email")));
inputElements.add(driver.findElement(By.id("join-password")));
// iterate over the List to send keys
for (int i = 0; i < var.length; i++) {
inputElements.get(i).sendKeys(var[i]);
}
}
May be instead of passing array/list you can create a class containing all the variable and accessors and modifier functions for each variable. Create the object of the class in getQuote() and append the values in the same function. Later you can simply pass the object.
And whenever you have new attribute you can simply add the attributes to the class and use the object anywhere.
considaring that you have only specified number of inputs on web page you may try like this.
public void getquote() {
String FirstName = "Sam";
String LastName = "Gayle";
String ZipCode = "10104";
String PhoneNumber = "212-225-8558";
CallGetQuote(FirstName, LastName, ZipCode, PhoneNumber);
}
public void CallGetQuote(String... var) {
List<Webelement> inputs = driver.findElements(By.tagName("input"));
for (int i = 0; i < var.length; i++) {
inputs.get(i).sendKeys(var[i]);
}
}
You may have to change the order of strings you are sending.
I tried printStackTrace and I have coverted everything to static (I think)... however, lines 17 and line 38 are the problem... because of this error:
You picked up: Pickaxe
java.lang.NullPointerException
at item.addInv(item.java:38)
at item.main(item.java:17)
Description: Can be used to mine with.
Press any key to continue . . .
Line 17: anItem.addInv(1);
Line 38: arr.add("Dan");
And here is my code:
import java.io.*;
import java.util.*;
import javax.swing.*;
public class item
{
public static int attack, defense;
public static ArrayList<String> arr;
public static String name, desc, typeOf, attackAdd, defenseAdd, canSell, canEat,earnedCoins,canEquip;
String stats[];
public static void main(String args[])
{
item anItem = new item();
ArrayList<String> arr = new ArrayList<String>();
anItem.addInv(1);
}
public static void addInv(int e) {
String iname = getItem(1)[0];
String idesc = getItem(1)[1];
int itypeOf = Integer.parseInt(getItem(1)[2]);
int iattackAdd = Integer.parseInt(getItem(1)[3]);
int idefenseAdd = Integer.parseInt(getItem(1)[4]);
boolean icanSell = Boolean.parseBoolean(getItem(1)[5]);
boolean icanEat = Boolean.parseBoolean(getItem(1)[6]);
int iearnedCoins = Integer.parseInt(getItem(1)[7]);
attack = attack + iattackAdd;
defense = defense + idefenseAdd;
System.out.println("You picked up: " + iname);
try {
arr.add("Dan");
} catch(NullPointerException ex) {
ex.printStackTrace();
}
System.out.println("Description: " + idesc);
}
public static String[] getItem(int e) {
String[] stats = new String[7];
String name = "Null";
String desc = "None";
String typeOf = "0";
String attackAdd = "0";
String defenseAdd = "0";
String canSell = "true";
String canEat = "false";
String earnedCoins = "0";
if (e == 1) {
name = "Pickaxe";
desc = "Can be used to mine with.";
typeOf = "2";
attackAdd = "2";
earnedCoins = "5";
}
return new String[] { name, desc, typeOf, attackAdd, defenseAdd, canSell, canEat, earnedCoins};
}
}
As you can see, it's those lines and I don't know what to do... :\
When you call the add() method on arr, it's not been initialized yet, hence, the NullPointerException.
Since you'll probably use the ArrayList in other methods as well, you should have that initialized in the constructor; ie:
public item() {
arr = new ArrayList<String>();
}
Variable arr is not initialized.
Variable arr in main() is not the same arr in function addInv()
Just initialize it in addInv to fix it.
String canEat = "false"; Why are you converting to and from strings?
You seem to have muddled an item class an inventory class.
Perhaps an Enum would be better:
public enum InventoryItem
{
PICKAXE("Pickaxe", "Can be used to mine with", ItemType.Tool,
5, 2, 0)
EPIC_PICKAXE("Super mega awesome Pickaxe", "Can be used to mine with, but epically", ItemType.Tool,
1000000, 100, 0)
public static enum ItemType {
TOOL,
WEAPON
}
public final String name, description;
public final ItemType type;
public final boolean canSell, canEat, canEquip;
public final int earnedCoins, attackAdd, defenseAdd;
private InventoryItem(String name, String description, ItemType type
int earnedCoins, int attackAdd, int defenseAdd,
boolean canSell, boolean canEat, boolean canEquip)
{
this.name = name;
this.description = description;
this.type = type
this.canSell = canSell;
this.canEat = canEat;
this.canEquip = canEquip;
this.earnedCoins = earnedCoins;
}
private InventoryItem(String name, String description, ItemType type
int earnedCoins, int attackAdd, int defenseAdd)
{
this(name, description, type,
earnedCoins, attackAdd, defenseAdd,
true, false, true);
}
}
Then you can just have List<InventoryItem> inventory = new ArrayList<InventoryItem>() within your player's class, and directly interface with that.
A few tips (one that does directly solve the problem):
1) wherever possible declare variables as private, or at most protected. I personally never use the "default" which is package level access (anything in the same package can see it).
2) Only use public for immutable values. An immutable value is something that cannot be changed (all members are final is the best way to ensure that, or no method modifies any values after the object is constructed and the variables are all private).
3) whenever possible always declare variables to be final (class variables, instance variables, parameters, local variables).
The one tip that directly helps you here is #3. Since you never assigned a value to "arr" it is null. If you declared it as final the compiler would force you do actually assign it a value, if you do not the code won't compile.
Doing that little thing will save you hours of time as you start programming. In my case I did something similar, not exactly the same (really I violated #2 sort of in a round about way) and it cost me about a week. I have been programming in Java for over 15 years now... if I can waste a week because of something like this think of how much time you can waste :-)