This question already has answers here:
Java: Error: variable might not have been initialized
(2 answers)
Closed 5 years ago.
I'm trying to do a method that checks if a book is rented and then if the book is in a directory. But I get a variable might not have been initialized error on checkIsBookAvailableToRent. I wonder it means the variable may be the out of scope. Can you help me improve this method, please?
package com.company.model;
import java.util.ArrayList;
import java.util.List;
public class BookDirectory {
private static List<Book> bookDirectoryList = new ArrayList<Book>();
RentDirectory rentedBooksList = new RentDirectory();
Book book = new Book("");
public boolean isBookAvailableToRent(String title){
boolean checkIsBookAvailableToRent;
book.setTitle(title);
for (Book bookInRentDirectory : rentedBooksList.getRentedBooks()) {
if (bookInRentDirectory.getTitle().equals(book.getTitle())) {
checkIsBookAvailableToRent = false;
}
else {
for (Book bookInBookDirectory : bookDirectoryList) {
if (bookInBookDirectory.getTitle().equals(book.getTitle())) {
checkIsBookAvailableToRent = true;
}
else {
checkIsBookAvailableToRent = false;
}
}
}
}
return checkIsBookAvailableToRent;
}
public List<Book> getBookDirectory() {
return bookDirectoryList;
}
}
When you declare checkIsBookAvailableToRent, give it a default value, for example,
boolean checkIsBookAvailableToRent = false;
This is needed in case your code does not enter the for loop for any reason, such as if rentedBooksList.getRentedBooks() is empty. In that case, the function wouldn't know what to return.
In general, whenever you do declare variables, it's a good rule of thumb to give them a default value (unless there is a reason not to). That way you don't need to be concerned with errors like this.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 11 months ago.
I'm working on a project for a Java class, and I can't seem to get past this NullPointerException. The project is a command-line LinkedIn program. One of the aspects I'm implementing is the ability to add a skillset to a user's profile.
I have a LinkedInUser class in which I define a TreeSet to hold these skillsets in the form of Strings entered by the user. I'm using TreeSet, because the assignment requires them to be sorted.
I define the TreeSet in the LinkedInUser class here:
private Set<String> skillsets = new TreeSet<>();
The action the user takes is defined in the AddSkillsetAction class:
String skillset;
System.out.println("Enter a skillset to add to your list:");
skillset = scanner.nextLine();
loggedInUser.addSkillset(skillset);
System.out.println(skillset + " has been added to your skillsets.");
And the String they enter is passed to the addSkillSet function in the LinkedInUser class:
public void addSkillset(String skillset) {
skillsets.add(skillset);
}
I keep getting a NullPointerException on the line:
skillsets.add(skillset);
What am I doing wrong? I've tested every level up to that line. I even tested the TreeSet inside the addSkillset function with this code:
if(skillsets == null) {
System.out.println("The TreeSet is null.")
}
It's telling me the TreeSet is null. I thought instantiating the Set with:
private Set<String> skillsets = new TreeSet<>();
would actually create an empty TreeSet, instead of it pointing to a null location. Why is my set "skillsets" still pointing to null? What am I doing wrong here?
EDIT:
Here are the full classes:
package edu.institution.asn2;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class LinkedInUser extends UserAccount implements Comparable<LinkedInUser>, Serializable {
private static final long serialVersionUID = 75648957489235739L;
private String type;
private List<LinkedInUser> connections = new ArrayList<>();
private Set<String> skillsets = new TreeSet<>();
public LinkedInUser(String username, String password) {
super(username, password);
}
#Override
public void setType(String type) {
this.type = type;
}
public String getType() {
return this.type;
}
// Add a connection to user's list
public void addConnection(LinkedInUser user) throws LinkedInException {
int index = connections.indexOf(user);
if (index >= 0) {
throw new LinkedInException("You are already connected with this user.");
}
else {
connections.add(user);
}
}
// Remove a connection from the user's connection list
public void removeConnection(LinkedInUser user) throws LinkedInException {
int index = connections.indexOf(user);
if (index < 0) {
throw new LinkedInException("You are NOT connected to this user.");
}
else {
connections.remove(index);
}
}
// Return a copy of the ArrayList of connections
public List<LinkedInUser> getConnections() {
ArrayList<LinkedInUser> copy = new ArrayList<>(connections);
return copy;
}
// Return the number of connections
public int getNumberOfConnections() {
return connections.size();
}
// Return the skillsets
public Set<String> getSkillsets(){
return skillsets;
}
// Add a skillset
public void addSkillset(String skillset) {
skillsets.add(skillset);
}
// Remove a skillset
public void removeSkillset (String skillset) {
if(skillsets.contains(skillset)){
skillsets.remove(skillset);
} else {
System.out.println(skillset + " is not in your skills list.");
}
}
// Override the compareTo function
#Override
public int compareTo(LinkedInUser user) {
int i = this.getUsername().compareToIgnoreCase(user.getUsername());
return i;
}
}
And the class to add a skillset:
package edu.institution.actions.asn7;
import java.util.Scanner;
import edu.institution.ApplicationHelper;
import edu.institution.UserRepository;
import edu.institution.actions.MenuAction;
import edu.institution.asn2.LinkedInUser;
public class AddSkillsetAction implements MenuAction {
#Override
public boolean process(Scanner scanner, UserRepository userRepository, LinkedInUser loggedInUser) {
String skillset;
System.out.println("Enter a skillset to add to your list:");
skillset = scanner.nextLine();
loggedInUser.addSkillset(skillset);
System.out.println(skillset + " has been added to your skillsets.");
ApplicationHelper.incrementSkillsetCount(skillset);
return true;
}
}
After I run and try to add a skillset, I get this error:
Exception in thread "main" java.lang.NullPointerException
at edu.institution.asn2.LinkedInUser.addSkillset(LinkedInUser.java:69)
at edu.institution.actions.asn7.AddSkillsetAction.process(AddSkillsetAction.java:19)
at edu.institution.ApplicationController.process(ApplicationController.java:61)
at edu.institution.LinkedInCLI.main(LinkedInCLI.java:39)
LinkedInUser.java:69 is:
skillsets.add(skillset);
By the way… Your naming is confusing. String skillset; should be String skill, and .addSkill not .addSkillset, because you are adding individual skills rather than adding a set.
Clarifying your naming may clarify your code. Notice the singular skill and plural skills naming used in code below.
You did not provide enough details to diagnose the problem. But I can show you some example code based on your descriptions.
Your problem may be related to your not properly instantiating the TreeSet. Notice in this code that you have a choice of at least two places in which to instantiate:
On the declaration line of skills.
In the constructor. (Code currently commented-out.)
The LinkedInUser class.
package work.basil.linkedin;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;
public class LinkedInUser
{
private String name;
private NavigableSet < String > skills = new TreeSet <>();
// Constructor
public LinkedInUser ( final String name )
{
this.name = name;
// this.skills = new TreeSet <>() ;
}
// Modifiers
public void setName ( String name ) { this.name = name; }
public void addSkill ( String skill ) { this.skills.add( skill ); }
// Getters
public String getName ( ) { return name; }
public Set < String > getSkills ( ) { return Set.copyOf( this.skills ); } // Return a unmodifiable copy of the set. (defensive programming)
}
For defensive programming, we return a copy of the set. This unmodifiable copy returned by Set.copyOf has no order. In some implementations, the order may even change arbitrarily for each iterator. If you want to return an ordered NavigableSet instead, do this:
Change the return type of the method to NavigableSet.
Change the code to pass the instance’s set to the constructor of another set.
public NavigableSet < String > getSkills ( ) { return new TreeSet <>(this.skills ); }
Usage.
LinkedInUser alice = new LinkedInUser( "Alice" );
LinkedInUser bob = new LinkedInUser( "Bob" );
alice.addSkill( "Yodeling" );
alice.addSkill( "Tap Dancing" );
bob.addSkill( "Juggling" );
System.out.println( alice.getName() + " does " + alice.getSkills() );
System.out.println( bob.getName() + " does " + bob.getSkills() );
System.out.println( List.of( alice , bob ) );
When run.
Alice does [Yodeling, Tap Dancing]
Bob does [Juggling]
[LinkedInUser{name='Alice', skills=[Tap Dancing, Yodeling]}, LinkedInUser{name='Bob', skills=[Juggling]}]
You said:
I thought instantiating the Set with:
private Set<String> skillsets = new TreeSet<>();
Yes, that would indeed instantiate a TreeSet object, and store a reference to that set in a variable named skillsets. I expect you are placing that code in the wrong location. Again, look at the two locations I suggested earlier in this Answer: on declaration line, or in constructor.
hi I'm rewriting a java code in C# and I'm stuck here:
public void printSolveInstructions() {
System.out.print(getSolveInstructionsString());
}
public String getSolveInstructionsString() {
if (isSolved()) {
return historyToString(solveInstructions);
} else {
return "No solve instructions - Puzzle is not possible to solve.";
}
}
public List<LogItem> getSolveInstructions() {
if (isSolved()) {
return Collections.unmodifiableList(solveInstructions);
} else {
return Collections.emptyList();
}
}
I know how to rewrite the first two methods (it's for referencing the last one) but I don't know the equivalent for Collections.unmodifiableList() and Collections.emptyList()
solveInstructions is of type List here's the declaration in java and C#:
private ArrayList<LogItem> solveInstructions = new ArrayList<LogItem>() // java
private List<LogItem> solveInstructions = new List<LogItem>() // c#
update
I rewrote the getSolveInstructions() method in this way:
public List<LogItem> getSolveInstructions()
{
if (isSolved())
{
return solveInstructions.AsReadOnly();
}
else
{
return new List<LogItem>();
}
}
Now the problem is ide gives me an error when I use .AsReadOnly()
Your method returns either a List<LogItem>, or an IReadOnlyCollection<LogItem> (produced by call to List<T>.AsReadOnly() method; however, your return type is List<LogItem>, which is incompatible with the IReadOnlyCollection<LogItem>. Change your method return type to IList<LogItem>, which works for both types.
Note, since this method can return either a read-only or a read-write list, calling code should check the returned collection's IsReadOnly property, before attempting to modify it.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am developing an App which uses the following code. It is generating an unexpected error as "Attempt to invoke virtual method on a null object reference". I do not understand the reason why this is happening. The error is thrown as the line containing t[i].setTestname(getData(exams[i]));. Could someone please point out what I am doing wrong. Could use some help over here.
void processTestPerformance()
{
String exams[],rawdata;
rawdata=data.toString();
int numberoftests=getNumbers("tabletitle03",rawdata);
Tests[] t= new Tests[numberoftests];
exams=new String[numberoftests];
rawdata=rawdata+"tabletitle03";
for(int i=0;i<numberoftests;i++)
{
int j=rawdata.indexOf("tabletitle03");
int k=(rawdata.substring(j+1)).indexOf("tabletitle03");
exams[i]=rawdata.substring(j,j+1+k);
t[i].setTestname(getData(exams[i]));
rawdata=rawdata.substring(k);
}
}
The code for class Tests is as follows:
public class Tests
{
public int numberofsubjects;
public String testname;
public Subject s[];
public void setS(Subject[] s)
{
this.s = s;
}
public void setNumberofsubjects(int numberofsubjects)
{
this.numberofsubjects = numberofsubjects;
s=new Subject[numberofsubjects];
}
public void setTestname(String testname)
{
this.testname = testname;
}
}
Thanks in Advance.
You create an empty array of Tests class, of size numberoftests
If you look inside that array you will find a sequence of null. Because you never initialize it.
You just need to populate the array so that t[i] will return an instance of your class.
In your for-cycle you can for example use the default constructor:
t[i] = new Tests();
// now you can manipulate the object inside the array
t[i].etTestname(getData(exams[i]));
for(int i=0;i<numberoftests;i++)
t[i]=new Tests();
That solved my problem.
This question already has answers here:
What is the reason behind "non-static method cannot be referenced from a static context"? [duplicate]
(13 answers)
Closed 8 years ago.
I have two errors both the same and they follow below:
class FBox {//...}
class FBPlayer
{
//Initialized instances
FBox game = new FBox();
**FBPillar pillar = new FBPillar();**
**FBObjects objects = new FBObjects();**
//Lots o Properties...
public boolean get_Alive() { return this.b_PlayerAlive; }
public void set_Alive(boolean alive) { this.b_PlayerAlive = alive; }
//My Error ridden Method
public void checkCollision()
{
if(get_YPos() >= **objects**.get_Ground())
^My Error was incorrect name for my instance
{
set_Alive(false);
}
else if(get_Bounds().intersects(**pillar**.get_Bounds()))
^My Error was incorrect name for my instance
{
set_Alive(false);
}
}
class FBPillar
{
public int get_Bounds() {return 'the variable'; }
}
class FBObjects
{
public int get_Ground() {return 'the variable'; }
}
The error is in the if statement as well as the else if statement
When i run it it returns the error:
FBox.java:178: error: non-static method get_Bounds() cannot be referenced from a static context
else if(get_Bounds().intersects(**FBPillar**.get_Bounds()))
The same error for the if statement but with FBObjects.get_Ground())
^
Whose bounds are you talking about? You probably mean
if (get_Bounds().intersects(pillar.get_Bounds())) {
…
}
I'd also add that
FBPlayer player = new FBPlayer();
means that a player contains a player, which is probably isn't what you intended.
This question already has answers here:
What causes "'void' type not allowed here" error
(7 answers)
Closed 10 months ago.
I'm learning to use classes and part of my assignment is to make this Car class. I'm getting an error on line 6 where I attempt to print of the results of the methods within the class. I think this means that I'm attempting to print something that doesn't exist and I suspect it's the mileage method. I tried changing it to return miles, but that didn't work either. Any ideas?
public class TestCar {
public static final void main(String args[]) {
Car c = new Car ();
c.moveForward(4);
System.out.println ("The car went" + c.mileage() + "miles."); // <-- L6
}
}
class Car {
public int miles = 2000;
public void moveForward(int mf) {
if (miles != 2000) {
miles += mf;
}
}
public void mileage() {
System.out.print(miles);
}
}
The error message is telling you exactly what is wrong -- you're trying to extract a result from a method that does not return a result.
Instead, have the mileage() method return a String, not print out a String.
public String mileage() {
return String.valueOf(miles);
}
Myself, I'd make this a getter method, and instead would do:
public int getMiles() {
return miles;
}
Car.mileage() is void, i.e., does not return anything. It needs to return something, like in:
public int mileage() {
return miles;
}