Why does this Java program work counter to my expectations? - java

Why does this program work counter to my expectations?
I expect: 1 50 47 50
I get: 0 50 0 50
class Poppet {
int i;
Poppet(int i) {
i = i;
}
}
class Ideone
{
private final int i = 50; // Initialized final
private final int j; // Blank final
private final Poppet p; // Blank final reference
// Blank finals MUST be initialized in the constructor:
public Ideone() {
j = 1; // Initialize blank final
p = new Poppet(1); // Initialize blank final reference
System.out.println(p.i);
}
public Ideone(int x) {
j = x; // Initialize blank final
p = new Poppet(x); // Initialize blank final reference
System.out.println(p.i);
}
public static void main (String[] args)
{
Ideone t = new Ideone();
System.out.println(t.i);
Ideone r = new Ideone(47);
System.out.println(r.i);
}
}
Can you please explain why?

Change:
Poppet(int i) {
i = i;
}
to:
Poppet(int i) {
this.i = i;
}
by doing i = i you're assigning the method argument to itself while what you really want to do is to assign it to the class member variable.

Local variable shadowing, as described in JLS 6.4.1.
If you want to set the instance variable i, you have to prefix it as in this.i.
class Poppet {
int i;
Poppet(int i) {
this.i = i;
}
}

Related

Method that checks if the method was already executed with that input

public class CatalanNumbers {
private int howManyVariaties;
private int catalanNumber;
private int catalanNumber;
public int catalan(int a) {
if (Method was never executed with that input) {
howManyVariaties++;
int catalanNumber = 0;
for (int i= 0; i < n; i++) {
catalanNumber += catalan(i) * catalan( n- 1 -i);
return catalanNumber
To sum it up I only want to check how the maximum stack depth is.
Can someone help me?
Add a Set to your class that keeps track of what input was used and check that set inside the method
public class CatalanNumbers {
private int howManyVariaties;
private int catalanNumber;
private int catalanNumber;
private Set<Integer> alreadyHandled = new HashSet<>();
public int catalan(int a) {
if (alreadyHandled.add(a)) {
//rest of code
}
}
//...
}

How to access an array from the main method?

public static int arraylistExample() {
int length [] = new int [10];
length[0] = 2;
length[1] = 3;
length[5] = 8;
return length [1];
}
I have written in the main method this:
System.out.println(length[5]);
Hence, my code looks like this:
import java.util.ArrayList;
public class Javanotes {
public static void main(String[] args) {
System.out.println(length[5]);
}
public static int arraylistExample() {
int length [] = new int [10];
length[0] = 2;
length[1] = 3;
length[5] = 8;
return length [1];
}
}
and I get a "0" what should I do?
1) The array is defined in the method scope of arraylistExample(). It is not visible from main().
2) The array will be empty if you never call the method.
You could change it in this way :
public class Javanotes {
static int length [];
public static void main(String[] args) {
System.out.println(arraylistExample()); // print 3
System.out.println(length[5]); // print 8
}
public static int arraylistExample() {
length = new int [10]; // init the static field
length[0] = 2;
length[1] = 3;
length[5] = 8;
return length [1];
}
}
But note that using static everywhere is generally not the right thing.
You do that for utility classes.
You should declare the function before calling it.
your function arraylistexample is not seen by the main class

Create a Single Random Value to Share Across Classes Java

Final(?) edit:
Leonardo Pina's solution looks like what I needed. Thank you all for your input! My code is now:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And the implementation in the other class:
public class Damage {
Roll r;
Damage(Roll r) {
this.r = r;
}
public int damageOut() {
int a = r.getR(); //roll value
return a * 2; //test math on r
}
}
Edit:
Thank you for the responses. However, it seems my use of this method was not clear. Apologies! This is what I need:
Call Roll class, get e.g. "12"
OtherClass1 receives "12" from Roll via getter
OtherClass2 also receives "12" from Roll via getter
Call Roll class again, get a new random number, e.g. "48"
OtherClass1 receives "48" from Roll via getter
OtherClass2 also receives "48" from Roll via getter
Using the solutions provided, Roll creates a single random number and never creates a new one again. I need Roll to create random numbers on demand, and then share that random number with other classes. I do not want it to only generate one number and then stop. I hope this makes sense. Thank you for the responses so far!
I have searched for and read the other threads of a similar topic (including this one, which is how I tried to solve my problem), but the methods I have tried have failed. I need to create a single random value and then use that same value across multiple classes.
My random class:
public final class Roll {
private static final Random r1 = new Random();
private final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
And a class where I call for the static value from the random class:
public class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
When I call the getter from OtherClass, the value is different than the getter from Roll. I would expect them to be the same value.
I call the values for testing like so:
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
Any guidance would be greatly appreciated. Have a good day.
When you create a new instance of OtherClass you also create a new instance of Roll, therefore, the rolls are different.
You need to make sure you are getting the value R from the same object Roll.
This could be achieved by using a singleton pattern for the Roll class, or you could specify the Roll object you want to use to get values, this way you could have several rolls for different purposes. i.e.
Edit:
Answering your edit: to get a new number, you should update the value of r in the Roll class whenever you generate a new value, for example, instead of returning a value, the level() method could update the r variable:
public final class Roll {
private static final Random r1 = new Random();
// We now attribute a value to r uppon construction
private final int r;
public Roll() {
level();
}
// Whenever level() is called the value of r is updated
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
this.r = r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class Game {
public static void main(String[] args) {
// Create the Roll obj
Roll myRoll = new Roll();
// Initialize the other objs with myRoll
Board board = new Board(myRoll);
Player player = new Player(myRoll);
// Do your comparison
int b = board.getRoll();
int p = player.getRoll();
// EDIT: get a new value
myRoll.level();
// Do your comparison once more
b = board.getRoll();
p = player.getRoll();
}
class Board {
Roll r;
Board(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
class Player {
Roll r;
Player(Roll roll) {
this.r = roll;
}
public int getRoll() {
return r.getR();
}
}
}
Probably the simplest way to make it work would be to field r in class Roll as static, so that the Roll class looks like this:
ublic final class Roll {
private static final Random r1 = new Random();
private static final int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
Or second approach would be to make Roll class a singleton.
Edit:
Since you have changed the intent of the question, and from what I understand you should look into Observer design pattern. It may be helpful for your case.
As someone said in the comments, you should follow the singleton design pattern, meaning that your variable r should be unique across all Roll class instances. To do this, your code will have to look something like this:
public class RandomTest {
public static void main(String[] args) {
Roll roll = new Roll();
int r = roll.getR();
OtherClass other = new OtherClass();
int o = other.getR();
}
}
class Roll {
private static Random r1 = new Random();
private static int r = level();
private static final int level() {
int s = 1, e = 100;
int r = r1.nextInt((e - s) + 1) + s;
return r;
}
public int itemType() {
boolean b = r1.nextBoolean();
int a = ((b) ? 1 : 2);
return a;
}
public int getR() {
return r;
}
}
class OtherClass{
Roll roll = new Roll();
int r = roll.getR();
public int getR() {
return r;
}
}
How about sharing the Roll instance?
Roll roll = new Roll();
// roll.roll(); // Unclear how you "refresh" the data
int r = roll.getR();
OtherClass other = new OtherClass(roll);
int o = other.getR();
assert(o == r);
class OtherClass {
private final Roll roll;
public OtherClass(Roll roll) {
this.roll = roll;
}
public int getR() {
return roll.getR();
}
}
Tip: I think a Dice class with a roll() method makes more sense.

Getting NullPointer Exception when declaring LinkedBlockingQueue<String>

This is the code I have. I have getting Null Pointer Exception in the last line of the constructor (workerQueue[i] = new LinkedBlockingQueue(100);):
public class QueueThreadPool {
private BlockingQueue<String>[] workerQueue;
private Thread[] workerThreads;
private int numQueues;
private int numThreads;
public QueueThreadPool(int numThreads, int numQueues) {
this.numQueues = numQueues;
this.numThreads = numThreads;
for(int i=1; i<=numQueues; i++){
workerQueue[i] = new LinkedBlockingQueue<String>(100);
}
}
public static void main(String args[]){
System.out.println("Start...");
new QueueThreadPool(50, 11);
System.out.println("End...");
}
Please help!
Thanks!!
Array workerQueue is not instantiated which you need to do.
private BlockingQueue<String>[] workerQueue;
workerQueue is a reference of BlockingQueue<String>[] type, not a Object.
But also you cannot create a generic array of BlockingQueue<String>. Instead of that create a List of BlockingQueue<String>. Ex -
private List<BlockingQueue<String>> workerQueue= new ArrayList<>();
you can also create the list Object at constructor.
private List<BlockingQueue<String>> workerQueue= new ArrayList<>();
public QueueThreadPool(int numThreads, int numQueues) {
this.workerQueue = new ArrayList<>(numQueues); // <-- initialize the field.
this.numQueues = numQueues;
this.numThreads = numThreads;
...
You haven't initialized workerThreads. You have to do something like workerQueue= new BlockingQueue<String>[numQueues];
Two problems in the code: the field need to be initialized, the loop should go from 0 to the array-size's - 1. Here is how the fixed code should look like:
public class QueueThreadPool {
private BlockingQueue<String>[] workerQueue;
private Thread[] workerThreads;
private int numQueues;
private int numThreads;
public QueueThreadPool(int numThreads, int numQueues) {
this.workerQueue = new BlockingQueue<String>[numQueues] // <-- You need to initialize the field.
this.numQueues = numQueues;
this.numThreads = numThreads;
for(int i=0; i < numQueues; i++){ // <-- Indexing into arrays goes from 0 to size-1 (inclusive).
workerQueue[i] = new LinkedBlockingQueue<String>(100);
}
}

Calling a method from a class array gives NullPointerException

I've been searching a lot for this problem and I can't find a solution. I'm trying to build a mini-game and I have a method for creating platforms. I have a class with every platform parameters, and I made a class array so i can have multiple platforms at the same time.
Problem: When I try to call the method for constructing the platform by sending the parameters I want, it gives me a NullPointerException. The method was working before, but with everything static and so i couldnt have multiple instances of that class, and now I removed the static fields from the platform class and it gives me the NullPointerException every time I call the method.
I copied the part of the code that gives me the error, the error goes the following way:
public static void main(String[] args) {
Game ex = new Game();
new Thread(ex).start();
}
In Game class:
public Load_Stage load = new Load_Stage();
public Game() {
-other variables initializatin-
Initialize_Items();
load.Stage_1(); // <--- problem this way
In Load_Stage class:
public class Load_Stage {
public Platforms plat = new Platforms();
public void Stage_1(){
Stage_Builder.Build_Platform(200, 500, 300, plat.platform1);
Stage_Builder.Build_Platform(100, 200, 100, plat.platform1);
}
}
And inside the Stage_Builder class:
public class Stage_Builder {
public static final int max_platforms = 10;
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
public static void Build_Platform(int x, int y, int width, ImageIcon[] type) { // BUILDS A PLATFORM
for (int b = 0; b < max_platforms; b++) {
if (platform_on[b] == false) {
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
platform_on[b] = true;
break;
}
}
}
}
Thanks beforehand.
EDIT: Here's the Platform_1 class (sorry for forgetting about it):
public class Platform_1 {
private int platform_begin_width = 30;
private int platform_middle_width = 20;
public int blocks_number = 0;
public ImageIcon[] platform_floors = new ImageIcon[500];
private int current_width = 0;
public int [] platform_x = new int [500];
public int platform_y = 0;
public int platform_width = 0;
public void Construct(int x, int y, int width, ImageIcon [] type) {
platform_width = width;
platform_y = y;
for (int c = 0; current_width <= platform_width; c++) {
if (c == 0) {
platform_x[c] = x;
platform_floors[c] = type[0];
current_width += platform_begin_width;
} else if ((current_width + platform_middle_width) > platform_width) {
platform_floors[c] = type[2];
blocks_number = c + 1;
platform_x[c] = current_width + x;
current_width += platform_middle_width;
} else {
platform_floors[c] = type[1];
platform_x[c] = current_width + x;
current_width += platform_middle_width;
}
}
}
}
And the Platforms class:
public class Platforms {
public ImageIcon[] platform1 = {new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/begin.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/middle.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/end.png")};
}
The problem and solution are both obvious.
public static Platform_1[] p1 = new Platform_1[max_platforms];
After this line of code executes, p1 is an array of references of type Platform_1 that are all null.
Executing this line of code tells you so right away:
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
The solution is to intialize the p1 array to point to non-null instances of Platform_1.
Something like this would work:
for (int i = 0; < p1.length; ++i) {
p1[i] = new Platform1();
}
I'm not seeing where you put things in the p1 array in the Stage_Builder class.
Another possibility (unlikely, but possible if you haven't shown everything) is that something in the Platform class, which you didn't show, is not initialized, and is breaking when you call Construct.
Also, the following seems problematic
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
it appears you declare static variables p1 and platform_on, but you only populate platform_on in a constructor. So the first time you create a Stage_Builder instance, you populate one static array with all false, and don't put anything in the other static array...
Populate those static variables in a static block
// static var declarations
static {
// populate static arrays here.
}
The array you are calling a message on was never filled.
You have
public static Platform_1[] p1 = new Platform_1[max_platforms];
so p1 is
p1[0] = null
p1[1] = null
.
.
.
p1[max_platforms] = null
You try to call
p1[b].Construct(x, y, width, type);
which is
null.Construct(...);
You need to initialize that index on the array first.
p1[b] = new Platform_1();
p1[b].Construct(...);
First of all, your problem is that p1[b] is most likely null, as duffymo pointed out.
Secondly, you are using arrays in a really weird way. What about
a) delete Stage_Builder
b) Instead, have an ArrayList somewhere
c) The equivalent of Build_Platform1() look like this, then:
p1.add(new Platform1(x, y, width, type);
d) no if on[i], no max_platforms, no for loop to add a platform (the latter is a bad performance problem if you actually have a few hundret platforms)

Categories