I just started learning java, with some minor prior experience in python and a bit of javascript, but not using classes. I have an issue with this code (just for reference, below that I point out exact issue):
public class Race {
Boolean isThereABrokenTruck = false;
private Car[] cars;
private Motorcycle[] motorcycles;
private Truck[] trucks;
private void createVehicles() {
cars = new Car[10];
motorcycles = new Motorcycle[10];
trucks = new Truck[10];
} // creates 10 cars, 10 trucks and 10 motorcycles.
private void simulateRace() {
Weather.setRaining();
for (Car car : cars) {
for (int i = 0; i < 50; i++) {
car.moveForAnHour();
}
}
for (Motorcycle motorcycle : motorcycles) {
for (int i = 0; i < 50; i++) {
motorcycle.moveForAnHour();
}
}
for (Truck truck : trucks) {
for (int i = 0; i < 50; i++) {
truck.moveForAnHour();
}
}
}
private void printRaceResults() {
for (Car car : cars) {
System.out.println("Name: " + car.name);
System.out.println("\n Distance Travelled: " + car.distanceTraveled);
System.out.println("\n Type:" + car.getClass().getName());
}
for (Motorcycle motorcycle : motorcycles) {
System.out.println("Name: " + motorcycle.name);
System.out.println("\n Distance Travelled: " + motorcycle.distanceTraveled);
System.out.println("\n Type:" + motorcycle.getClass().getName());
}
for (Truck truck : trucks) {
System.out.println("Name: " + truck.name);
System.out.println("\n Distance Travelled: " + truck.distanceTraveled);
System.out.println("\n Type:" + truck.getClass().getName());
}
} // prints each vehicle's name, distance traveled ant type.
protected Boolean isThereABrokenTruck() {
return isThereABrokenTruck;
}
public static void main(String[] args) {
Race race = new Race();
race.createVehicles();
race.simulateRace();
race.printRaceResults();
}
}
This code compiles (classes Car, Motorcycle and Truck are defined in my code as well, but are not relevant to the question), however I get runtime null pointer exception on
for (Car car : cars) { // null pointer exception here
for (int i = 0; i < 50; i++) {
car.moveForAnHour();
}
}
so I guess I am not assigning value to cars properly. I am forced to have separate methods to create those vehicles, operate on them and print the results to console. In python I'd probably just return multiple arrays (or lists) and assign their values to different variables, but how do I do it here in Java?
You initialize your vehicle array:
private void createVehicles() {
cars = new Car[10];
motorcycles = new Motorcycle[10];
trucks = new Truck[10];
}
But your array now contains only null-car, null-trucks...
You need to initialize them as well:
private void createVehicles() {
cars = new Car[10];
for (int i = 0; i < cars.length; i++) {
cars[i] = new Car();
}
motorcycles = new Motorcycle[10];
trucks = new Truck[10];
// Init other vehicles as well
}
initial arrays in constructor
public Race() {
createVehicles();
}
You are creating cars variable to hold 10 instances of Car but not storing any value. Add some values to the array and try.
when you initial an array you fill the array with nulls.
so
Car[] cars = new Car[10];
means you have an array with 10 nulls in it. and you are iterating on it. and you will get NullPointerException here car.moveForAnHour();
in createVehicles() you must fill it with objects.
for example :
private void createVehicles() {
cars = new Car[10];
for(int i = 0; i < cars.length; i++) {
cars[i] = new Car();
}
}
Related
Here is my code:
package bikeproject;
import java.util.ArrayList;
import java.util.Random;
public class BikerList {
public static void main(String[] args) {
ArrayList<Bike> bikes = new ArrayList<Bike>();
int mountainBikeSales = 0;
int roadBikeSales = 0;
fillArray(bikes);
displayStock(bikes);
// calculateStock(bikes);
System.out.println(displayBkeNumbers(bikes));
}
static void fillArray(ArrayList<Bike> bikes) {
Random rand = new Random();
// int number = 2;
// int a = rand.nextInt(2);
for (int i = 0; i < 10; i++) {
if (rand.nextInt(2) < 1) {
// System.out.println(rand.nextInt(2));
bikes.add(new MountainBike());
} else {
// System.out.println(rand.nextInt(2));
bikes.add(new RoadBike());
}
}
}
static void displayStock(ArrayList<Bike> bikes) {
for (Bike bike : bikes) {
System.out.println(bike);
}
}
static int calculateStock(ArrayList<Bike> bikes) {
int bikesSold = 0;
for (Bike bike : bikes) {
if (bikes.contains(new MountainBike())) {
bikesSold++;
}
}
return bikesSold;
}
static String displayBkeNumbers(ArrayList<Bike> bikes) {
int mb = 0;
int rb = 0;
mb = calculateStock(bikes);
rb = bikes.size() - mb;
return "\nStock Levels" + "\nWe have " + mb + " mountain Bike in Stock" + "\nWe have " + rb
+ " Road bikes in Stock";
}
}
I really believe there is an error in the calculateStock() method because it always returns false, In the calculateStock() method I want to add the value to the bikesSold variable if each bike in the array is an instance of a mountain bike.
The output generated by the code above:
Stock Levels
We have 0 mountain Bike in Stock
We have 10 Road bikes in Stock
Mountain Bike is always 0 although it is already in the ArrayList.
The expected output, something like this:
Stock Levels
We have 4 Mountain Bikes in stock
We have 6 Road Bikes in stock
static int calculateStock(ArrayList<Bike> bikes) {
int bikesSold = 0;
for (Bike bike : bikes) {
if (bikes.contains(new MountainBike())) { //problematic line
bikesSold++;
}
}
return bikesSold;
}
does not work, because, .contains(Object o):
returns true if and only if this list contains at least one element e such that Objects.equals(o, e).
So, bikes.contains(new MountainBike()) will always return true as long as there is, at least, one instance of the MountainBike contained (according to the .equals(Object o) method) in the bikes list.
Rather, you should want to check if the current object is an instance of a particular type you would want to check it against (MountainBike, in this case), like this:
static int calculateStock(ArrayList<Bike> bikes) {
int bikesSold = 0;
for (Bike bike : bikes) {
if (bike instanceof MountainBike) {
bikesSold++;
}
}
return bikesSold;
}
This if (bikes.contains(new MountainBike())) creates a new object and checks if it's already in the list. It's not.
You need to do something like if (bike instanceof Mountainbike) .
There are better ways, but that will solve your problem.
I'm supposed to display the rainfall value for the STATE that I want to search. How do I go about doing this?
rainfall class:
package rainfallassignment;
public class StateRainfall {
double rainAmt[]; //declare array value entered by user
int num_state = 11; //number of states in west malaysia
public StateRainfall(double rain[]) {
rainAmt = rain;
}
}
Test program:
package rainfallassignment;
import java.util.Scanner;
public class TestRainfall {
public static void main(String[] arg) {
Scanner reader = new Scanner(System.in);
//declare constant to store size of array
int num_state = 11;
//declare array to store rainfall data
double rain[] = new double[num_state];
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for (int i = 0; i < num_state; i++) {
System.out.println("Enter Rain value for each state: "
+ state[i] + ": ");
rain[i] = reader.nextDouble();
}
//create rainfall object
StateRainfall rain1 = new StateRainfall(rain);
for (int i = 0; i < num_state; i++) {
System.out.println("Rainfall for " + state[i] + " is: " + rain[i]);
}
}
}
Is there a special command I should use to search and display the rainfall for a particular state?
Several remarks to your code:
Instead of having two (synchronised) arrays better use a Map. The main purpose of a Map is to associate a value to a key:
Iterating is better done with forEach, or - since java8 - with streams.
Always be careful with naming your variables. A variable name should clearly show its intention. An array called "state" is misleading when reading the code. Since it is a collection, better use the plural "states".
Constants: Your comment "declare constant to store size of array" is wrong, since you define a local variable. Constants are better defined outside methods within the class body as
private static int NUM_STATE= 11;
It is also good practice to choose another naming style for constants (here: capital letters), which helps you later reading your own code.
A resource (like Scanner) should always be closed in order to release used memory. In my example done by a try-with-resource construct. You can also use try..finally blocks.
Following these tips, your code would boil down to this:
public static void main( String[] args)
{
Scanner reader = new Scanner(System.in);
Map<String, Double> rainMap = new HashMap<>();
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for ( String s : state )
{
System.out.println("Enter Rain value for each state: "
+ s + ": ");
rainMap.put( s, reader.nextDouble());
}
rainMap.keySet().forEach(k -> System.out.println("Rainfall for " + k + " is: " + rainMap.get(k)));
}
I think, the question for "search and display" is implicitely also answered.
I suggest that your StateRainfall keep tracks of both states and rain values, like this
// class
class StateRainfall {
String[] states;
double rainAmt[]; //declare array value entered by user
int num_state; //number of states in west malaysia
public StateRainfall(String[] states, double rain[]) {
this.states = states;
rainAmt = rain;
num_state = states.length;
}
}
This will allow you to look into states array and return the corresponding rain value from the index
double getRain(String state) {
for (int i = 0; i < num_state; i++) {
if (states[i].equals(state)) {
return rainAmt[i];
}
}
return -1;
}
// Just a toString() method for convenience
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < num_state; i++) {
sb.append("Rainfall for ").append(states[i]).append(" is: ").append(rainAmt[i]);
}
return sb.toString();
}
And use all of this like
StateRainfall rain1 = new StateRainfall(state, rain);
System.out.println(rain1);
System.out.println(rain1.getRain("Kelantan"));
You can implement such thing using Map like this :
public class StateRainfall {
Map<String, Double> rainfall;
public StateRainfall(String[] states, double[] rainFall) {
this.rainfall = new HashMap<>();
for (int i = 0; i < states.length; i++)
this.rainfall.put(states[i], rainFall[i]);
}
public static void main(String[] arg) {
Scanner reader = new Scanner(System.in);
//declare constant to store size of array
int num_state = 11;
//declare array to store rainfall data
double[] rain = new double[num_state];
//array representing states
String[] state = {"Perlis", "Kedah", "Penang", "Perak",
"Kelantan", "Terengganu", "Pahang",
"Selangor", "Negeri Sembilan", "Malacca", "Johor"};
for (int i = 0; i < num_state; i++) {
System.out.println("Enter Rain value for each state: "
+ state[i] + ": ");
rain[i] = reader.nextDouble();
}
//create rainfall object
StateRainfall rain1 = new StateRainfall(state, rain);
System.out.println("Enter state for rainfall report:");
String stateName = reader.next();
System.out.println("Rainfall for " + stateName + " is: " + rain1.getRainFall(stateName));
}
public double getRainFall(String state) {
return this.rainfall.get(state);
}
}
I have a program and I am trying to reduce the cost of the books by 40%. Now my issue is that I am able to reduce any book in the array that I specifiy but not every book in the array. I'm unsure of how to get the method to go every element in the array. I know that it is changing the index because I have 0 in [0] for example. My question is what do I do so it sorts through the whole array and not just the one index. This is happening in the reduceBook method.
public static void main(String[] args) {
Book[] bookArray = new Book[6];
bookArray[0] = new Book("Java Proramming", "Liang", 1320, 145.00);
bookArray[1] = new Book("Horton Hears a Who", "Dr. Seuss", 72, 19.99);
bookArray[2] = new Book("The Hobbit", "Tolkien", 320, 9.25);
bookArray[3] = new Book("Born a Crime", "Noah", 304, 17.33);
bookArray[4] = new Book();
bookArray[5] = new Book();
for(Book b : bookArray)
System.out.println(b);
finishArray(bookArray);
System.out.println("\nThis is a space between the old array and the new finished one ");
for(Book b : bookArray)
System.out.println(b);
System.out.println("\nThis should print out the discounted books ");
reduceBooks(bookArray);
for(Book b : bookArray)
System.out.println(b);
}
// public void finishArray(String[] Book) {
public static void finishArray(Book[] bookara) {
bookara[4].setTitle("The Town");
bookara[4].setAuthor("Chuck Hogan");
bookara[4].setPages(477);
bookara[4].setPrice(14.99);
bookara[5].setTitle("Cat and Mouse");
bookara[5].setAuthor("James Patterson");
bookara[5].setPages(358);
bookara[5].setPrice(9.99);
}
public static Book reduceBooks(Book[] reduceAra) {//This is the trouble area
Book bookReduce = reduceAra[0]; //So here if I change the index
//it will reduce the book in it by 40% but I need to reduce all the books in the array.
double price = bookReduce.getPrice();
for (int i = 0; i < reduceAra.length; i++) {
double reducedPrice = price * .60;
bookReduce.setPrice(reducedPrice);
}
return bookReduce;
}
Just loop through the book array like you did to print, but instead lower the cost
for(Book b : bookArray) {
b.setPrice(b.getPrice() * 0.6)
}
You can code the method reduceBook this way:
public static void reduceBooks(Book[] reduceAra) {
for (int i = 0; i < reduceAra.length; i++) {
Book bookReduce = reduceAra[i];
double price = bookReduce.getPrice();
double reducedPrice = price * .60;
bookReduce.setPrice(reducedPrice);
}
}
or even in a more compact style:
public static void reduceBooks(Book[] reduceAra) {
for (int i = 0; i < reduceAra.length; i++) {
Book bookReduce = reduceAra[i];
bookReduce.setPrice(bookReduce.getPrice() * 0.60);
}
}
Dominique Ubersfeld
just loop the reduceBooks method
public static Book reduceBooks(Book[] reduceAra) {
for(Book b : reduceAra){
double price = b.getPrice();
price = price * .60;
b.setPrice(price);
}
return bookReduce;
}
i'm trying to get the enum values one by one using a for loop without the need to specify all possible values like i'm doing in the code Value.As be replaced by something like Value.values()but when i try this it doesn't work for me :
public class Deck {
private LinkedList<Card> cardList;
public Deck(int nbBox) {
this.cardList = new LinkedList<Card>();
for (int i = 0; i < nbBox; i++) {
for (int j = 0; j < 52; j++) {
cardList.add(new Card(Value.AS, Color.CLUB));
}
}
}
public Card draw() {
return null; // not done yet
}
#Override
public String toString() {
return "Here is the deck : " +cardList;
}
public LinkedList<Card> getCardList() {
return cardList;
}
public void setCardList(LinkedList<Card> cardList) {
this.cardList = cardList;
}
}
You could use a for-each loop on the values(). This reads as for each suit, for each value add a new card with the suit and value to the List. Also, you could use diamond operator <> like,
public Deck(int nbBox) {
this.cardList = new LinkedList<>(); // <-- diamond operator
for (int i = 0; i < nbBox; i++) {
for (Suit suit : Suit.values()) {
for (Value value : Value.values()) {
cardList.add(new Card(suit, value));
}
}
}
}
Try this:
enum Mobile {
Samsung(400), Nokia(250),Motorola(325);
int price;
Mobile(int p) {
price = p;
}
int showPrice() {
return price;
}
}
public class EnumDemo {
public static void main(String args[]) {
System.out.println("CellPhone List:");
for(Mobile m : Mobile.values()) {
System.out.println(m + " costs " + m.showPrice() + " dollars");
}
Mobile ret = Mobile.Samsung;
System.out.println("The ordinal is = " + ret.ordinal());
System.out.println("MobileName = " + ret.name());
}
}
The output will be:
CellPhone List:
Samsung costs 400 dollars
Nokia costs 250 dollars
Motorola costs 325 dollars
The ordinal is = 0
MobileName = Samsung
I am learning java and was trying some stuff. This is what I am trying to do.
I am trying to create an table of an array of an object.
e.g. I am creating an object called animal by which i can add any number of animal and its breed on user choice.
package tt;
import java.util.Scanner;
public class animal {
String aname;
String abreed;
public animal() {
mainprog aa = new mainprog();
System.out.printf("eneter name of your %s..\n", aa.Animalcat);
Scanner name = new Scanner(System.in);
aname = name.nextLine();
System.out.printf("eneter breed of your %s..\n", aa.Animalcat);
Scanner breed = new Scanner(System.in);
abreed = breed.nextLine();
}
public String getbreed() {
return abreed;
}
public String getname() {
return aname;
}
}
So the main program ask for how many animals I want to add.
package tt;
import java.util.Scanner;
public class mainprog {
public static String Animalcat;
public static void main(String[] args) {
System.out.println("How many animals you want to add..");
Scanner an = new Scanner(System.in);
int animalNumbers = an.nextInt();
animal[][] addAnimal = new animal[animalNumbers][1];
animaltype[] at = new animaltype[animalNumbers];
for (int i = 0; i < animalNumbers; i++) {
at[i] = new animaltype();
Animalcat = at[i].getAnimalType();
for (int j = 0; j < 1; j++) {
addAnimal[i][j] = new animal();
}
}
Display(addAnimal, at);
}
public static void Display(animal x[][], animaltype y[]) {
System.out.println("Your animals are..");
for (int m = 0; m < x.length; m++) {
System.out.printf("Following are the name and the breed of %s ",
y[m].getAnimalType());
System.out.println();
for (int n = 0; n < x[m].length; n++) {
System.out.printf(" %s", x[m][n].aname);
System.out.printf(" %s", x[m][n].abreed);
System.out.println();
}
}
}
}
package tt;
import java.util.Scanner;
public class animaltype {
String animalType;
public animaltype() {
System.out.println("What kind of animal you want to add..");
Scanner at = new Scanner(System.in);
animalType = at.nextLine();
}
public String getAnimalType(){
return animalType;
}
}
The issue I have here is I can ask for how many types of animals I want to add but I can't control how many animals of that type I want to add.
While adding animal I can only add 1 number of animal manually by declaring it as [1] and can't by user input.
addAnimal = new animal[animalNumbers][1];
The problem in if I can do that by declaring animal[][] addAnimal = null; and then later initialize it with like:
animal[][] addAnimal = new animal[animalNumbers][animaltypenumbers];
But I get NullPointerException all time. Is there anyway I can have this done?
When you create an array, it will be filled by the default value of the element it contains. Since Animal is an Object, then it will be filled by null values, and you cannot use any variable which has null value. Since you're just filling animal[i][0] in your current code, you won't get any problem. But it will appear when you try to access to animal[i][1]. This happens in Display method:
public static void Display(animal x[][], animaltype y[]) {
System.out.println("Your animals are..");
for (int m = 0; m < x.length; m++) {
System.out.printf("Following are the name and the breed of %s ",
y[m].getAnimalType());
System.out.println();
for (int n = 0; n < x[m].length; n++) {
//you only filled elements in x[m][0]
//x[m][n] when n > 0 is null
//so you will get NullPointerException
System.out.printf(" %s", x[m][n].aname);
System.out.printf(" %s", x[m][n].abreed);
System.out.println();
}
}
}
A better option:
Use Animal[] addAnimal instead, you don't need it to have it as an array of arrays:
public static void main(String[] args) {
System.out.println("How many animals you want to add..");
Scanner an = new Scanner(System.in);
int animalNumbers = an.nextInt();
animal[] addAnimal = new animal[animalNumbers];
animaltype[] at = new animaltype[animalNumbers];
for (int i = 0; i < animalNumbers; i++) {
//at[i] = new animaltype();
//Animalcat = at[i].getAnimalType();
Animalcat = new animaltype();
//for (int j = 0; j < 1; j++) {
// addAnimal[i][j] = new animal();
//}
addAnimal[i] = Animalcat;
}
Display(addAnimal, at);
}
//modify Display method accordingly
A better option:
Use List<Animal> backed by ArrayList<Animal> instead of Animal[]. List let's you handle a list of elements that grows dynamically.
public static void main(String[] args) {
System.out.println("How many animals you want to add..");
Scanner an = new Scanner(System.in);
int animalNumbers = an.nextInt();
List<Animal> animals = new ArrayList<Animal>();
for (int i = 0; i < animalNumbers; i++) {
Animalcat = new animaltype();
animals.add(Animalcat);
}
Display(animals);
}
//modify Display method accordingly