Enhanced for-loop stopped with NullPointerException - java

My enhanced for loop doesn't seem to be iterating correctly. The purpose is to use the search class to go through an ArrayList of type Contact and find a specific name but for some reason it only goes through the first contact and stops with an error after that displaying:
Exception in thread "main" java.lang.NullPointerException
at client.AddressBook.search(AddressBook.java:17)
at Main.main(Main.java:31)
My Main class is below:
import client.AddressBook;
import client.Contact;
public class Main {
public static void main(String[] args) {
AddressBook ab = new AddressBook();
Contact c1 = new Contact("jeffm#engr.uconn.edu");
ab.add(c1);
Contact c2 = new Contact("jeffm#engr.uconn.edu", "Jeff Meunier", "jeff");
ab.add(c2);
Contact c3 = new Contact("billgates#engr.uconn.edu", "Bill Gates", "bill");
ab.add(c3);
System.out.println(ab.search("jeff"));
}
}
The AddressBook and Contact class are also listed below:
package client;
import java.util.ArrayList;
public class AddressBook {
ArrayList<Contact> al = new ArrayList<Contact>();
public void add(Contact contactAdd) {
al.add(contactAdd);
}
public Contact search(String searchName) {
for(Contact obj: al) {
if(obj.getNickName().equals(searchName)) {
return obj;
}
}
return null;
}
public String remove(String nickname) {
search(nickname);
al.remove(nickname);
return nickname;
}
public void show() {
int x = 1;
for(Contact obj: al) {
System.out.println(x + ". " + obj.toString());
x++;
}
}
}
package client;
public class Contact {
public String _emailAddress = null;
public String _fullName = null;
public String _nickName = null;
public Contact(String emailaddress, String fullname, String nickname) {
_emailAddress = emailaddress;
_fullName = fullname;
_nickName = nickname;
}
public Contact(String emailaddress) {
_emailAddress = emailaddress;
}
#Override
public String toString() {
if(_fullName == null & _nickName == null) {
//System.out.println("<" + _emailAddress + ">");
return _emailAddress;
}
else {
//System.out.println(_fullName + " (" + _nickName + ") " + "<" + _emailAddress + ">");
return _fullName + " (" + _nickName + ") " + "<" + _emailAddress + ">";
}
}
public String getNickName() {
return _nickName;
}
}
If anyone can give any pointers it would be greatly appreciated. Ultimately right now I am only testing to see whether the search class can search for a specified nickname and then print out the returned value of that. Obviously it should be returning the second Contact (or at least that is the intention).

The problem happen in this validation :
if(obj.getNickName().equals(searchName)) {
return obj;
}
It seems like obj.getNickName() may sometime be null.
Change the order of your validation :
public Contact search(String searchName) {
for(Contact obj: al) {
//I assume that searchName will never be null
if(searchName.equals(obj.getNickName()) {
return obj;
}
}
return null;
}

Your first item you add does not include a nickname. in your search you get the nickname and call equals() on a null reference.

Related

How can i verify if i'm adding atributes to a list that are equal?

import entidades.*;
public class Main {
public static void main(String[] args) {
Profissional prof = new Profissional(null, null);
List<Profissional> profissional = new ArrayList<Profissional>();
Scanner sc = new Scanner(System.in);
boolean loop = true;
while(loop == true) {
String comando = sc.next().toUpperCase();
if (comando.contentEquals("RP")) {
String nomePro = sc.nextLine();
String categoriaPro = sc.nextLine();
prof.NomeVerificacao(profissional, nomePro, categoriaPro);
}
if(comando.contentEquals("SAIR")) {
break;
}
}
for(Profissional pro : profissional) {
System.out.println(pro);
This is my Main, it's running fine but i don´t think it is adding the atributes to the list and not verifying either.
i want to add the atributes to a list so i can create different objets but they can not have at least the name equal.
public class Profissional {
private String nome;
private String categoria;
public Profissional(String nome, String categoria) {
this.nome = nome;
this.categoria = categoria;
}
public void NomeVerificacao(List<Profissional> profissional ,String nome, String categoria) {
if(profissional.isEmpty() == true) {
profissional.add(new Profissional(nome, categoria));
}else {
for(Profissional pro : profissional) {
if(pro.nome.contentEquals(nome)) {
System.out.println("Já Exite esse nome");
}else {
profissional.add(new Profissional(nome, categoria));
}
}
}
}
#Override
public String toString() {
return "nome=" + nome + ", categoria=" + categoria;
}
}
this is the Profissional Class.
I'm almost there i think but the output keeps saying that the name exists even though it is the first name i'm inserting.
I ran your code on my machine and made 3 changes into it, and it's working for me now,
1)
String nomePro = sc.next();
String categoriaPro = sc.next();
2) In professional class just changed this function a bit:
public void NomeVerificacao(List<Profissional> profissional, String nome, String categoria) {
if (profissional.isEmpty() == true) {
profissional.add(new Profissional(nome, categoria));
} else {
int i = 0;
for (; i < profissional.size(); i++) {
if (profissional.get(i).nome.equals(nome)) {
System.out.println("Já Exite esse nome");
break;
}
}
if (i == profissional.size()) {
profissional.add(new Profissional(nome, categoria));
}
}
}
3) At the end of the class Main, wrote sc.close(); to close the scanner.
i/p and o/p :
1) RP
red
color
2) RP
orange
color
3) RP
orange
paint
Já Exite esse nome
4) SAIR
nome=red, categoria=color
nome=orange, categoria=color
As you can see in above i/p and o/p, nome=red and nome=orange with categoria=color are added in the list but when we tried to add the same nome=orange again but with different category as paint it didn't add it and printed the message "Já Exite esse nome".
and after entering SAIR, the toString(); printed the list content at the end. So the message will be printed only if we try to add the object with the same name again int list (not the first or any other times).
Further optimizations are possible but for now, it will work!
I can propose the following solution:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// Set is a data structure that makes sure you don't have a duplicated elements
// in this case we use TreeSet structure that accepts comparator which tells that
// we need to compare elements only by professional's name
Set<Profissional> profissionals = new TreeSet<>(Comparator.comparing(Profissional::getNome));
while (true) {
String comando = sc.next().toUpperCase();
if (comando.contentEquals("RP")) {
String nomePro = sc.next();
String categoriaPro = sc.next();
// add function returns true in case the element we're going to add
// was not presented in Set structure yet. False otherwise.
boolean isNew = profissionals.add(new Profissional(nomePro, categoriaPro));
if (!isNew) {
System.out.println("Professional with name " + nomePro + " already exists");
} else {
System.out.println("Professional with name " + nomePro + " was added");
}
} else if (comando.contentEquals("SAIR")) {
break;
}
}
// just prints all professionals at the end of the program
profissionals.forEach(System.out::println);
}
public static class Profissional {
private String nome;
private String categoria;
public Profissional(String nome, String categoria) {
this.nome = nome;
this.categoria = categoria;
}
// getters and setters
#Override
public String toString() {
return "nome=" + nome + ", categoria=" + categoria;
}
}
The output will be the following:
RP
test test
Professional with name test was added
RP
test1 test1
Professional with name test1 was added
RP
test test3
Professional with name test already exists
SAIR
nome=test, categoria=test
nome=test1, categoria=test1
package javaapplication8;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class JavaApplication8 {
public static class Profissional {
private String nome;
private String categoria;
public Profissional(String nome, String categoria) {
this.nome = nome;
this.categoria = categoria;
}
}
public static void main(String[] args) {
try {
List<Profissional> profissionalList= new ArrayList<>();
Scanner sc = new Scanner(System.in);
while(true) {
System.out.print("\r\nEnter comando:");
String comando = sc.next().toUpperCase();
if (comando.contentEquals("RP")) {
System.out.print("nome: ");
String nome = sc.next();
sc.nextLine(); // wait enter
System.out.print("categoria: ");
String categoria = sc.next();
sc.nextLine(); // wait enter
// access constructor of Profissional
Constructor profCtor = Profissional.class.getConstructor(String.class, String.class);
profCtor.setAccessible(true);
// create instance of Profissional
Profissional newItem = (Profissional) profCtor.newInstance(nome, categoria);
// avoid duplicate nome in profissionalList
boolean isExist = false;
for(Profissional pro : profissionalList) {
if(pro != null){
if(pro.nome.toLowerCase().equals(newItem.nome.toLowerCase())){
isExist = true;
break;
}
}
}
if(!isExist){
profissionalList.add(newItem );
}
}
if(comando.contentEquals("SAIR")) {
break;
}
}
for(Profissional pro : profissionalList) {
if(pro != null) {
System.out.println("nome: " + pro.nome + " categoria: " + pro.categoria);
}
}
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}

How can I use a string attribute of a class to refer to that class in java?

I have the following 3 classes that is meant to represent a program that allows a user to create a sort of database that can add people and their phone numbers and addresses and then search for them once created.
Here are the classes:
Person
import java.util.*;
public class Person implements Comparable<Person> {
private final String name;
private String street;
private String city;
private String address;
public Person(String name) {
this.name = name;
this.address = "address unknown";
}
public String getName() {
return name;
}
public void setAddress(String street, String city){
this.city = city;
this.street = street;
this.address = this.street + " " + this.city;
}
public String getAddress() {
return address;
}
#Override
public int compareTo(Person o) {
return this.name.compareToIgnoreCase(o.getName());
}
}
PhoneNumbers (to store the person + their phone numbers)
import java.util.*;
import java.util.Collections;
public class PhoneNumbers {
private Map<Person, Set<String>> numbers;
public PhoneNumbers() {
this.numbers = new HashMap<Person, Set<String>>();
}
public void addPhoneNumber(Person person, String phoneNumber){
if(!this.numbers.keySet().contains(person)){
this.numbers.put(person, new HashSet<String>());
}
this.numbers.get(person).add(phoneNumber);
}
public Set<String> searchByPerson(Person person){
if(!this.numbers.keySet().contains(person)){
return this.numbers.get(person);
}
return null;
}
public String searchByNumber(String number){
for(Person person : this.numbers.keySet()){
Set<String> x = this.numbers.get(person);
for(String y : x){
if(y.equals(number)){
return person.getName();
}
}
}
return " not found";
}
public void personalSearch(Person person){
System.out.println(" " + person.getAddress());
if(this.numbers.get(person).size() == 0){
System.out.println(" phone number not found");
}
for(String x : this.numbers.get(person)){
System.out.println(" phone numbers");
System.out.println(" " + x);
}
}
public void remove(Person person){
this.numbers.remove(person);
}
public List<Person> masterSearch(String search){
ArrayList<Person> names = new ArrayList<Person>();
for(Person person : this.numbers.keySet()){
if(person.getName().contains(search) || person.getAddress().contains(search)){
names.add(person);
}
}
Collections.sort(names);
return names;
}
public Map<Person, Set<String>> getNumbers() {
return numbers;
}
}
UI (to provide the way for the user to interact with the program)
import java.util.Scanner;
public class UI {
private Scanner reader;
private PhoneNumbers phoneNumbers;
public UI() {
this.reader = new Scanner(System.in);
this.phoneNumbers = new PhoneNumbers();
}
public void start(){
System.out.println("phone search\n" +
"available operations:\n" +
" 1 add a number\n" +
" 2 search for a number\n" +
" 3 search for a person by phone number\n" +
" 4 add an address\n" +
" 5 search for personal information\n" +
" 6 delete personal information\n" +
" 7 filtered listing\n" +
" x quit\n");
while(true){
System.out.print("command: ");
int command = Integer.parseInt(reader.nextLine());
System.out.println("");
if(command == 1){
System.out.print("whose number: ");
String name = reader.nextLine();
System.out.print("number: ");
String number = reader.nextLine();
Person person = new Person(name);
this.phoneNumbers.addPhoneNumber(person, number);
}
else if(command == 2){
System.out.print("whose number: ");
String person = reader.nextLine();
//something here
}
}
else{
System.out.println(" not found");
}
}
}
}
}
I have a question with the code in the UI specifically
else if(command == 2){
System.out.print("whose number: ");
String person = reader.nextLine();
when the command is given as 2 I ask the user for a name and that is given as a string, how do I then use that String to find the value of the person object with that name under the HashMap i.e. the set of numbers associated with the person.
Obviously I cannot do this with a get method on the map as the keys are person objects not strings and I don't know what to do (do I need to store a map between String name and Person name), I believe in this context names are unique?
Also bonus question: why would I be getting an error when I do command 1 and give a number that is not all digits like "045-4558" for instance.
Thank you
Maybe something like that:
for (Map.Entry<Person, Set<String>> entry : numbers.entrySet()) {
Person key = entry.getKey();
if (key.getName().equals(nameWhichYouAreLookingFor)) {
//Do whatever you want
}
}

Using toString() method from child class

Hi I am writing a code using polymorphism and I would like to print List on the screen but when I am using my code it run toString method from parent class only. How can I fix it?
public class HospitalApp {
public static void main(String[] main){
Hospital hospital = new Hospital();
List<Person> lista = new ArrayList<>();
lista = hospital.showList();
StringBuilder stringBuilder = new StringBuilder();
for(Person person : lista){
stringBuilder.append(person);
stringBuilder.append("\n");
}
System.out.println(stringBuilder.toString());
}
}
public class Hospital{
List<Person> lista = new ArrayList<>();
Person doktor = new Doctor("All", "Bundy",100, 99999);
Person nurse = new Nurse("Iga", "Lis",160, 10);
Person nurse_1 = new Nurse("Magda", "Andrych",160, 20);
public List showList(){
lista.add(doktor);
lista.add(nurse);
lista.add(nurse_1);
return lista;
}
}
public class Person{
private String imie;
private String nazwisko;
private double wyplata;
public Person(){}
public Person(String imie, String nazwisko, double wyplata){
this.imie = imie;
this.nazwisko = nazwisko;
this.wyplata = wyplata;
}
public void setImie(String imie){
this.imie = imie;
}
public String getImie(){
return imie;
}
public void setNazwisko(String nazwisko){
this.nazwisko = nazwisko;
}
public String getNazwisko(){
return nazwisko;
}
public void setWyplata(double wyplata){
this.wyplata = wyplata;
}
public double getWyplata(){
return wyplata;
}
public String toString(){
return getImie() + " " + getNazwisko() + " " + getWyplata();
}
}
public class Nurse extends Person{
private int nadgodziny;
public Nurse(){}
public Nurse(String imie, String nazwisko, double wyplata, int nadgodziny){
super(imie, nazwisko, wyplata);
this.nadgodziny = nadgodziny;
}
public void setNadgodziny(int nadgodziny){
this.nadgodziny = nadgodziny;
}
public int getNadgodziny(){
return nadgodziny;
}
#Override
String toString(){
return getImie() + " " + getNazwisko() + " " + getWyplata() + " " + getNadgodziny();
}
}
public class Doctor extends Person {
private double premia;
public Doctor(){}
public Doctor(String imie, String nazwisko, double wyplata , double premia){
super(imie, nazwisko, wyplata);
this.premia = premia;
}
public double getPremia(){
return premia;
}
public void setPremia(double premia){
this.premia = premia;
}
#Override
String toString(){
return getImie() + " " + getNazwisko() + " " + getWyplata() + " " + getPremia();
}
}
Can someone help me solve this problem?
The problem lies here, in the Person and Doctor class:
#Override
String toString(){
return ...;
}
you are missing the public specifier. There should be an error / warning about that. Apply it to the method signatures and your code will work as you expect it to.
probably you should add to the List not a Person (object) but a value returned by its toString method:
for(Person person : lista){
stringBuilder.append(person.toString);
stringBuilder.append("\n");
}

Need various ways to come up with this output

I am supposed to come up with this output.
But I am getting this instead..
Here is my code:
import java.lang.*;
import java.util.*;
import java.io.*;
public class Sample{
private String name;
private Hashtable customers = new Hashtable();
private Hashtable movies = new Hashtable();
public Sample(String aName){
name = aName;
}
public String getName(){
return name;
}
public void setName(String aName){
name = aName;
}
public void addCustomer (Customer customer) {
customers.put(customer.getName(), customer);
}
public Customer getCustomer (String customerName) {
return (Customer)customers.get(customerName);
}
public void addMovie (Movie movie) {
movies.put(movie.getName(), movie);
}
public Movie getMovie (String movieName) {
return (Movie)movies.get(movieName);
}
public void error (String message) {
System.out.println ("ERROR: " + message);
}
public Enumeration getMovies() {
return movies.elements();
}
public Enumeration getCustomers() {
return customers.elements();
}
public void showAll() {
System.out.println ("name: "+ this.getName());
Enumeration kk = this.getCustomers();
while (kk.hasMoreElements()) {
Customer one = (Customer) kk.nextElement();
System.out.println (one.show());
}
Enumeration ff = this.getMovies();
while (ff.hasMoreElements()) {
Movie one = (Movie) ff.nextElement();
System.out.println (one.show());
}
}
public void test() {
Customer k1 = new Customer ("Jonah") ; this.addCustomer (k1);
Customer k2 = new Customer ("Hellen") ; this.addCustomer (k2);
Customer k3 = new Customer ("Agnes") ; this.addCustomer (k3) ;
Movie f1 = new Movie ("StarWars"); this.addMovie (f1) ;
Movie f2 = new Movie ("Shrek"); this.addMovie (f2) ;
System.out.println("-**-**- test part 1 -**-**-") ;
this.showAll();
System.out.println("-**-**- test part 2 -**-**-") ;
System.out.println("---" + k1.getName() + " rents " + f1.getName());
this.showAll();
k1.doRent(f1);
MY CUSTOMER CLASS:
package eric;
public class Customer {
String name;
public Customer(String nameCus){
name = nameCus;
}
public String getName(){
return name;
}
public String show(){
return name;
}
public void doRent(Movie f1) {
System.out.println(" -"+ " RentData" + "[" + getName() +"," + f1.getName() + "]" );
}
}
MY MOVIE CLASS:
public class Movie {
String name;
int x = 0;
public Movie(String nameMov){
name = nameMov;
}
public String getName(){
return name;
}
public String show(){
return name+"\n"+" - average: "+x +" days\n"+" - number of rentings: "+x ;
}
}
My problem is that i cannot find a way to fix -RentData [Jonah,StarWars] under the name Jonah... Instead it comes at the end of output.. I need some one to help me figure how am ganna do that.. thanks
You're calling k1.doRent(f1) before this.showAll() so naturally you will get the "RentData..." line printed before the names are printed. The way your code is now is not conducive to what you're trying to do at all. Your Customer class should have a member list called rentedMovies that is populated every time you call doRent(...) on a Customer object. Then, Customer.show() should print the name of the customer, followed by your "RentData..." stuff that comes from rentedMovies.

NullPointerException when adding Object to ArrayList

I'm very new to Java and have been trying to set-up an ArrayList CustomerList that takes object Customer, where Customer has attributes from class IAddress. When calling the .add method in my main code however, I am given a NullPointerException error, which I assume is being given because my method isn't receiving anything to add to the ArrayList. I thought it was an issue with the attributes being initialised to empty strings, but when editing them to contain some information, the error still occured.
The ArrayList CustomerList
public class CustomerList {
public ArrayList<Customer> Clients;
public CustomerList() {
Clients = new ArrayList<>();
}
public void add(Customer src) {
Clients.add(src);
}
public void remove(Customer src) {
Clients.remove(src);
}
public void Display(JTextArea jClientsTextArea) {
for (int i = 0; i < Clients.size(); i++) {
Clients.get(i).Display(jClientsTextArea);
}
}
}
Receives Customer from this class
public class Customer {
private String FirstName;
private String Surname;
private IAddress HomeAddress;
public String DOB;
public Customer() {
FirstName = "";
Surname = "";
DOB = "01/01/1900";
HomeAddress = new IAddress();
public void Display(javax.swing.JTextArea jAddressTextArea) {
jAddressTextArea.setLineWrap(true);
jAddressTextArea.append("First Name: " + FirstName + "\n");
jAddressTextArea.append("Surname: " + Surname + "\n");
jAddressTextArea.append("DOB:" + DOB + "\n");
jAddressTextArea.append("Street: " + HomeAddress.getStreet() + "\n");
jAddressTextArea.append("House Name: " + HomeAddress.getHouseName() + "\n");
jAddressTextArea.append("House Number: " + HomeAddress.getHouseNo() + "\n");
jAddressTextArea.append("Area: " + HomeAddress.getArea() + "\n");
jAddressTextArea.append("Postcode: " + HomeAddress.getPostCode() + "\n");
jAddressTextArea.append("Town: " + HomeAddress.getTown() + "\n");
jAddressTextArea.append("Country: " + HomeAddress.getCountry() + "\n");
}
public void Edit(String strfirstname, String strsurname, String strDOB, String strStreet, String strHouseName, String strHouseNo, String strHouseArea, String strPostCode, String strTown, String strCountry) {
FirstName = strfirstname;
Surname = strsurname;
DOB = strDOB;
HomeAddress.setStreet(strStreet);
HomeAddress.setHouseName(strHouseName);
HomeAddress.setHouseNo(strHouseNo);
HomeAddress.setArea(strHouseArea);
HomeAddress.setPostCode(strPostCode);
HomeAddress.setTown(strTown);
HomeAddress.setCountry(strCountry);
}
}
Which receives attributes from IAddress
public class IAddress {
private String Name;
private String Street;
private String HouseNo;
private String HouseName;
private String Area;
private String PostCode;
private String Town;
private String Country;
public IAddress() {
Name = "";
Street = "";
HouseNo = "";
HouseName = "";
Area = "";
PostCode = "";
Town = "";
Country = "";
}
public void setName(String strName) {
Name = strName;
}
public void setStreet(String strStreet) {
Street = strStreet;
}
public void setHouseNo(String strHouseNo) {
HouseNo = strHouseNo;
}
public void setHouseName(String strHouseName) {
HouseName = strHouseName;
}
public void setArea(String strArea) {
Area = strArea;
}
public void setPostCode(String strPostCode) {
PostCode = strPostCode;
}
public void setTown(String strTown) {
Town = strTown;
}
public void setCountry(String strCountry) {
Country = strCountry;
}
}
I've been banging my head against this problem for hours and am ready for it to be something stupidly simple. Thank you.
In your code above the only reason why calling myCustomerList.add(...) could throw is that myCustomerList itself is null. This is because the Clients inside it is initialized in the constructor, and never set to null again. The value of src does not matter as well - the call to Clients.add(src) would succeed even if src is null.
You need to make sure that in your main you do initialize your customer list, like this:
CustomerList list = new CustomerList();

Categories