Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to create a Java program that manage a booking ticket system.
I have a film Class:
public class Film {
private String title;
private Double price;
private String ageRestriction;
private double rating;
private String genre;
private String location;
private String screenDay;
A FilmList Class that create an ArrayList of Films item and sort, based by two parameters (Location and Week)
public class FilmList {
public FilmList(ArrayList<Film> filmArrayList) {
this.filmArrayList = filmArrayList;
}
public FilmList (){
this.filmArrayList = new ArrayList<>();
}
public ArrayList <Film> filmArrayList;
public void addFilm(Film films){
this.filmArrayList.add(films);
}
private String showLocation;
private String screenWeek;
public void setScreenWeek(String screenDay) {
this.screenWeek = screenDay;
}
public String getScreenWeek() {
return screenWeek;
}
public void setShowLocation(String location) {
this.showLocation = showLocation;
}
public String getShowLocation() {
return showLocation;
}
public Optional<Film> searchFilm(){
Optional<Film> movieFounded = filmArrayList.stream().filter(i -> i.getLocation().contains(getShowLocation()) &&
i.getScreenDay().contains(getScreenWeek())).findAny();
return movieFounded;
}
The setShowLocation parameter it's stetted by the click of a button (there's one of them for each theatre, and the setScreenWeek it's stetted by a Combobox
the Graphic unit interface with the console. Notice that if I press the button without select anything on the combobox I got an error.
So
FilmList filmList = new FilmList();
filmList.addFilm
System.out.println(searchFilm().toString());
Your code is a bit strange, but I suppose you meant passing a Film instance to addFilm, and then using filmList.searchFilm().
Anyway
filter(
i -> i.getLocation().contains(getShowLocation()) &&
i.getScreenDay().contains(getScreenWeek())
)
Here you're filtering the filmArrayList, which contains a single element at that point. And
i.getLocation().contains(getShowLocation())
means basically
i.getLocation().contains(null)
as the showLocation field isn't initialized.
The same applies for the second condition, using screenWeek.
I'm actually surprised it doesn't throw a NullPointerException, as
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1; // NullPointerException at s.toString()
}
But anyway, let's say you initialized those fields, then the only element is discarded by the filter operation, that's why you see Optional.empty.
final FilmList filmList = new FilmList();
filmList.setShowLocation("Your location");
filmList.setScreenWeek("Screen week");
filmList.addFilm(filmInstance);
System.out.println(filmList.searchFilm().toString());
You obviosly need a fully constructed Film instance
final Film filmInstance = new Film();
filmInstance.title = "The NullPointerException adventure";
filmInstance.price = 12D;
filmInstance.ageRestriction = "+18";
filmInstance.rating = 18D;
filmInstance.genre = "Horror";
filmInstance.location = "US";
filmInstance.screenDay = "Monday";
filmList.addFilm(filmInstance);
The problem is in the FilmList#setShowLocation method.
You're assigning showLocation to itself, and the location parameter is unused.
public void setShowLocation(String location) {
this.showLocation = showLocation;
}
This should be
public void setShowLocation(String location) {
this.showLocation = location;
}
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.
I have 2 classes. one is named "shipment", the other is called "Inventory"
inside the shipment, there are some variables as below.
public class Shipment
{
private int trackingCode;
private int priority;
private double shippingPrice;
private double weight;
private String originCity;
private String destCity;
private String trackingPage;
and I create the "Inventory" as below
public class Inventory
{
private ArrayList<Shipment> packages;
public Inventory(Shipment[] listOfPackage)
{
if(listOfPackage == null){
throw new IllegalArgumentException("List of Packages cannot be null.");
}
packages = new ArrayList<Shipment>(Arrays.asList(listOfPackage));
}
Now my question is how do I create a method to add a new package to the ArrayList, and also duplicate tracking code is not allowed need to throw an exception.
public ArrayList<Package> addPackage()
I'm very confusing how to do the duplicate tracking code check because it's one of the Shipment[] array element
You can use the this keyword to refer to your private member variables and still keep a similar naming convention for parameters passed into your constructor or functions. It makes your code much more understandable to others and to yourself =). Having two separate naming conventions for everything you pass into a class can get very confusing.
I have added a main function to demonstrate how you would effectively operate on these classes.
public class Application {
public static void main(String[] args) {
// define some unique shipments
Shipment a = new Shipment(1,1, 10.0, 20.3, "Denver", "Seattle", "xyz");
Shipment b = new Shipment(2,9, 45.88, 130.1, "Denver", "Los Angeles", "xyz");
Shipment c = new Shipment(3,3, 14.67, 6.8, "Houston", "Dallas", "xyz");
Shipment d = new Shipment(1,4, 12.99, 2.3, "New York", "London", "xyz");
// populate your inventory with an array of initial shipments "a", "b", and "c"
Shipment[] initialShipments = new Shipment[] { a, b, c };
Inventory inventory = new Inventory(initialShipments);
// print the inventory before adding the new shipment
System.out.println(inventory.toString());
// add shipment "d" to your inventory with the new method
try {
inventory.addShipment(d);
}
catch (Exception e) {
System.out.println(e.getMessage());
}
// print the inventory after adding the new shipment
System.out.println(inventory.toString());
}
}
For your Inventory:
public class Inventory {
private ArrayList<Shipment> shipments;
public Inventory(Shipment[] shipments) {
if(shipments == null) {
throw new IllegalArgumentException("List of shipments cannot be null.");
}
this.shipments = new ArrayList<>(Arrays.asList(shipments));
}
public void addShipment(Shipment shipment) throws Exception {
Optional<Shipment> duplicateShipment = shipments
.stream()
.filter(otherShipment -> otherShipment.getTrackingCode() == shipment.getTrackingCode())
.findAny();
if(duplicateShipment.isPresent()) {
String errorMessage = MessageFormat.format(
"A shipment with tracking code {0} already exists in this inventory.",
shipment.getTrackingCode()
);
throw new Exception(errorMessage);
}
else {
this.shipments.add(shipment);
}
}
#Override
public String toString() {
return "Inventory{" +
"shipments=" + shipments +
'}';
}
}
In order to check for duplicate tracking codes, you must make a stream of your existing shipments so that you can look for any tracking code in those shipments that match the one you are trying to add.
There are many ways to accomplish this in theory, but I did it by making a stream of your shipments so I could make a filter that looked for any shipment tracking code equal to the one you are adding.
The findAny at the end of this stream just returns an Optional which means that it could potentially return something or not.
With the Optional type, you can test if it found a duplicate by using the isPresent() function. If the duplicate is present, you can throw an exception, as needed.
Here I just made the function throw up the Exception, but you could handle it here in the function and just log that you tried to add the same shipment. In real code, you wouldn't want your code to break because you tried to add a duplicate shipment. You would just want to stop it from happening and move on!
For your Shipment:
public class Shipment {
private int trackingCode;
private int priority;
private double shippingPrice;
private double weight;
private String originCity;
private String destCity;
private String trackingPage;
public Shipment(int trackingCode, int priority, double shippingPrice, double weight, String originCity, String destCity, String trackingPage) {
this.trackingCode = trackingCode;
this.priority = priority;
this.shippingPrice = shippingPrice;
this.weight = weight;
this.originCity = originCity;
this.destCity = destCity;
this.trackingPage = trackingPage;
}
public int getTrackingCode() {
return trackingCode;
}
}
You need to add a 'getter' to the Shipment class so that you can access the tracking code outside of this class; otherwise, it will remain private, and you won't be able to make comparisons outside of this class where you need to check for duplicate tracking codes.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, this is a class where I store data from another class called (Name)
the class (Name) got 3 informations. Name (String)/Number List /Adress List I used the last 2 as a List so I can allow multiple adresses/numbers
now the thing is, i can't get my getContact in this code to work, it doesn't return anything, so i thought that i messed up somewhere, checked everything and things were right, so i bypassed toString and printed an object of the type Namebook is my main method and it worked just fine.
public class Namebook {
private ArrayList<Name> contact;
private Name ctc;
public Namebook(){
contact = new ArrayList<Name>();
}
public void addContact(Name name){
this.contact.add(name);
}
public String getContact(){
return String.valueOf(this.contact);
}
#Override
public String toString() {
return String.valueOf(this.contact);
}
}
Class (Name)
public class Name {
private String name;
private List<String> number;
private List<String> Adress;
public Name(String name){
this.name = name;
}
public void addNumber(List<String> num){
this.number = num;
}
public void addAdress(List<String> adress){
this.Adress = adress;
}
public List<String> getNumber(){
return this.number;
}
public List<String> getAdress(){
return this.Adress;
}
public String toString() {
return this.name + " " + getNumber() + " " + getAdress() ;
}
}
Main
public class Main {
Scanner reader = new Scanner(System.in);
public static void main(String[] args) throws Exception {
Name person = new Name("sacha");
ArrayList<String> add = new ArrayList<String>();
ArrayList<String> num = new ArrayList<String>();
add.add("chicago");
num.add("13213223");
person.addNumber(num);
person.addAdress(add);
//System.out.println(person);
Namebook p1 = new Namebook();
p1.addContact(person);
p1.getContact();
}
}
Your toString and getContact methods are identical, and behave identically.
Case 1:
System.out.println(person);
This is short for
System.out.println(person.toString());
Case 2:
p1.getContact();
This is not short for anything. But notice that you do not have a System.out.println statement. That is what prints the output of the method. Without that, nothing is printed. To fix it
System.out.println(p1.getContact());
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I am very new to Java... been at it for about 4 weeks... be gentle.
I am trying to get my takeItem method (below) to pass the itemName variable back to my Player Class so I can add an item from my current room to my player. I get the compiler error: Constructor Item in class Item cannot be applied to given types..
my end goal is to get the player class to hold the object after removing it from the room.
takeItem Method:
private void takeItem(Command command)
{
if(!command.hasSecondWord()) {
// if there is no second word, we don't know where to go...
System.out.println("Take what?");
System.out.println();
return;
}
String itemName = command.getSecondWord();
Item theItem;
// Try to take an item.
theItem = new Item(player.getCurrentRoom().removeItem(itemName));
if (theItem == null)
{
System.out.println("There is no item!");
}
else
{
player.addItem(theItem);
player.getItemsCarried();//print item info
}
Player Class:
//above code omitted//
public void setCurrentRoom(Room room)
{
currentRoom = room;
}
public Room getCurrentRoom()
{
return currentRoom;
}
//code below omitted//
public void addItem (Item thingy)
{
items.put(thingy.getName(), thingy);
}
//code below omitted//
Item Class:
public class Item
{
// instance variables - replace the example below with your own
private String name;
private String description;
private int weight;
/**
* Constructor for objects of class Item
*/
public Item(String n, String d, int w)
{
name = n;
description = d;
weight = w;
}
//code below omitted//
Room Class:
public class Room
{
private String description;
private HashMap <String, Room> exits;
private HashMap <String, Item> items;
//some code below omitted//
public Room (String description)
{
this.description = description;
exits = new HashMap<>();
items = new HashMap<>();
}
public void addItem (Item thingy)
{
items.put(thingy.getName(), thingy);
}
public String removeItem(String thingy)
{
items.remove(thingy);
return thingy;
}
//code below omitted
Your constructor in the Item class takes two String parameters and one int, but you are trying to create a new Item by passing in only one String (whatever is returned by the removeItem() method). You can either change the removeItem() method so that it returns the Item that is removed, in which case you should change
theItem = new Item(player.getCurrentRoom().removeItem(itemName));
to
theItem = player.getCurrentRoom().removeItem(itemName);
or you can create a new Item with the necessary parameters.
I encountered problem I am unable to solve. Thing is, my TableView is already populated and I need for cells that match my criteria to set value zero. I have variable korZemljiste and if my condition is fullfilled cells in column colOsnovica need to be set to value 0.00.
Here is what I tried:
if (korZemljiste < 10000)
{
tblTabela.getItems().stream().forEach((o)
-> {
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn());
colOsnovica.setOnEditCommit(
new EventHandler<CellEditEvent<Nepokretnost, Number>>() {
#Override
public void handle(CellEditEvent<Nepokretnost, Number> t) {
((Nepokretnost) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setOsnovica(t.getNewValue());
}
});});}
Sorry, for ugly end of code, couldn't make to copy it properly.
This part I modified from Oracle example and I get error:
error: incompatible types: no instance(s) of type variable(s) S exist so that Callback<TableColumn<S,String>,TableCell<S,String>> conforms to Callback<TableColumn<Nepokretnost,Number>,TableCell<Nepokretnost,Number>>
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn());
where S is a type-variable:
S extends Object declared in method forTableColumn()
error: incompatible types: Number cannot be converted to double
).setOsnovica(t.getNewValue());
My TableView using <Nepokretnost, Number> form.
Note: I guess I don't need this example from Oracle site because I don't want to manually change contents of cell in column, I just want to set them to value 0.00.
Some easy solution anyone?
Thanks in advance.
For the first error, since your table column type is not a String, you cannot use the no-argument version of TextFieldTableCell.forTableColumn(). The underlying problem is that, to edit the cell, the text field provides a String and the data in the cell is a Number. You need to provide a converter, using the overloaded form of TextFieldTableCell.forTableColumn(...):
colOsnovica.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
For the second error, just replace t.getNewValue() (which returns a Number) with t.getNewValue().doubleValue() (which gets the double representation of the Number).
#james-d
Hm, my mistake. Class is simple, here it is:
package obracun;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
/**
*
* #author Dalibor
*/
public class Nepokretnost {
private final SimpleStringProperty tipNepokretnosti;
private final SimpleStringProperty zona;
private final SimpleStringProperty pravo;
private final SimpleDoubleProperty povrsina;
private final SimpleDoubleProperty amortizacija;
private final SimpleDoubleProperty osnovica;
private final SimpleDoubleProperty kredit;
private final SimpleDoubleProperty porez;
public Nepokretnost(String tipNepokretnosti, String zona, String pravo,
Double povrsina, double amortizacija, Double osnovica, Double kredit, Double porez) {
this.tipNepokretnosti = new SimpleStringProperty(tipNepokretnosti);
this.zona = new SimpleStringProperty(zona);
this.pravo = new SimpleStringProperty(pravo);
this.povrsina = new SimpleDoubleProperty(povrsina);
this.amortizacija = new SimpleDoubleProperty(amortizacija);
this.osnovica = new SimpleDoubleProperty(osnovica);
this.kredit = new SimpleDoubleProperty(kredit);
this.porez = new SimpleDoubleProperty(porez);
}
public String getTipNepokretnosti() {
return tipNepokretnosti.get();
}
public void setTipNepokretnosti(String tipNepokretnosti) {
this.tipNepokretnosti.set(tipNepokretnosti);
}
public String getZona() {
return zona.get();
}
public void setZona(String zona) {
this.zona.set(zona);
}
public String getPravo() {
return pravo.get();
}
public void setPravo(String pravo) {
this.pravo.set(pravo);
}
public double getPovrsina() {
return povrsina.get();
}
public void setPovrsina(double povrsina) {
this.povrsina.set(povrsina);
}
public double getAmortizacija() {
return amortizacija.get();
}
public void setAmortizacija(double amortizacija) {
this.amortizacija.set(amortizacija);
}
public double getOsnovica() {
return osnovica.get();
}
public void setOsnovica(double osnovica) {
this.osnovica.set(osnovica);
}
public double getKredit() {
return kredit.get();
}
public void setKredit(double kredit) {
this.kredit.set(kredit);
}
public double getPorez() {
return porez.get();
}
public void setPorez(double porez) {
this.porez.set(porez);
}
}
I didn't realized it is necessary to post class here. I had this application made before just in Swing. There I just changed contents of JTableView field. This is kinda different, thanks for help.
I posted and screenshot of app. On screenshot I already added elements in TableView I wanted. Code I posted in question is part of Calculate (Обрачун) button event handler. In this example calculation should change the contents of field Основица to 0.00.