I have a class Floor which has a Stack of Blocks and I don't know how to initialize it. I had tried like this:
public class Floor {
private Stack<Block> stack;
private static int size;
public void setStack(Stack<Block> stack) {
this.stack = stack;
}
public void addBlock(Block b){
stack.push(b);
}
}
public class InputDevice {
Block a0=new Block('I',false);
Floor [] floor=new Floor[5];
Stack<Block> stack=new Stack<Block>();
floor[0].setStack(stack);
floor[0].addBlock(a0);
}
Floor [] floor=new Floor[5];
you declared the array, but you didn't init the elements, then :
floor[0].setStack(stack); floor[0] is null, npe!
also I suggest that in your Floor class, addBlock(Block b) method, check if the stack is null, if it is null, otherwise it would have problem(NPE) if someone init Floor, and directly floor.addBlock(b).
You've not initialized any of the Floor objects in the array yet. When you create an array of objects it's like creating an egg carton. You can't use any eggs until you put some in the carton first. You can't use any objects in the array before you've initialized them, which is often done within a for loop. i.e.,
Floor [] floor=new Floor[5];
for (int i = 0; i < floor.length; i++) {
floor[i] = new Floor();
}
try this code
public class Floor {
private Stack<Block> stack;
private static int size;
public void setStack(Stack<Block> stack) {
this.stack = stack;
}
public void addBlock(Block b){
stack.push(b);
}
}
public class InputDevice {
Block a0=new Block('I',false);
Floor [] floor=new Floor[5];
floor[0] = new Floor();
Stack<Block> stack=new Stack<Block>();
floor[0].setStack(stack);
floor[0].addBlock(a0);
}
Related
I am trying to create Expression Tree using the Postfix Expression.
This needs a Stack which could hold Tree Objects.
I created a generic Stack class which could except <TreeTemp> as type argument.
On trying to initialize the stack with following statement, its giving "Cannot infer type arguments for TreeStack<>" error.
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
Stack Class:
public class TreeStack<T> {
private T [] stackElem;
private final int MAXSTACKSIZE;
private int top;
public TreeStack(Class<T> t) {
top = -1;
MAXSTACKSIZE = 20;
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
this.stackElem = stackElem;
}
public void push(T elem) throws Exception{
if(isFull()) {
stackElem[++top] = elem;
}
else
throw new Exception("Stack is already Full");
}
public T pop() throws Exception {
if(isEmpty()) {
return stackElem[top--];
}
else
throw new Exception("Stack is Empty");
}
public boolean isEmpty() {return top == -1;}
public boolean isFull() {return top==MAXSTACKSIZE-1;}
}
Postfix.class(Class having method for creating tree)
public class PostFix {
private String expression = new String("A*B+C");
private char [] expElem = expression.toCharArray();
/*Error on below Statement*/
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
public TreeTemp makeTree() throws Throwable {
try {
for(int i=0;i<expElem.length;i++) {
ExpNode eNode = new ExpNode();
eNode.setiData(expElem[i]);
TreeTemp t = new TreeTemp();
t.setRoot(eNode);
if(!Character.isLetter(expElem[i])) {
t.setLeftTree(stack1.pop());
t.setRightTree(stack1.pop());
}
stack1.push(t);
}
return stack1.pop();
}catch (Exception e) {
throw new Exception("Stack Error while creating a Tree", e);
}
}
public static void main(String[] args) throws Throwable {
PostFix pf = new PostFix();
TreeTemp t = pf.makeTree();
}
Tree Class(Type which i want to add into Stack):
public class TreeTemp {
private ExpNode root;
private TreeTemp leftTree;
private TreeTemp rightTree;
/*public TreeTemp(ExpNode expNode) {
root = expNode;
}*/
public TreeTemp getLeftTree() {
return leftTree;
}
public void setLeftTree(TreeTemp leftTree) {
this.leftTree = leftTree;
}
public TreeTemp getRightTree() {
return rightTree;
}
public void setRightTree(TreeTemp rightTree) {
this.rightTree = rightTree;
}
public ExpNode getRoot() {
return root;
}
public void setRoot(ExpNode node) {
this.root = node;
}
}
Can someone pls give some pointers.
Your TreeStack has only one constructor. Here it is:
public TreeStack(Class<T> t) {
Thus, to invoke it, you need to pass the class object that represents the class associated with the T type. So, the class itself, not 'some particular instance of T'. When you call it on your error line:
private TreeStack<TreeTemp> stack1 = new TreeStack<>(new TreeTemp());
You are passing an instance of TreeTemp. Not the concept 'TreeTemp, the class'. Try new TreeStack<>(TreeTemp.class);
Note that as a general rule, passing a Class<T> is a code smell; you're trying to make generics something that it isn't (you're trying to runtime reify). This is objectively bad: It means you can't make a TreeStack<List<String>>, for example, because you're restricted to the overlap where both generics as well as j.l.Class instances can represent the thing, and that's just simple, non-genericsed, non-primitive classes.
final T[] stackElem = (T[]) Array.newInstance(t, MAXSTACKSIZE);
Looks like the only reason you want that class is to make sure your array is properly typed.
This is not neccessary. Just make a new Object[] array, and cast to T anytime you need to return a T. Now your TreeStack constructor needs no arguments at all.
Check the source of java.util.ArrayList, which agrees with this assessment; it is backed by an Object array, not a T[].
The TreeStack constructor accepts a Class<T>, not a T, so you should do:
new TreeStack<>(TreeTemp.class);
Since this is an exercise to create expression trees, you don't really need to implement stacks from scratch. You should just use the ArrayDeque class through the Deque interface in the Java Collections API.
private Deque<TreeTemp> stack1 = new ArrayDeque<>();
Deque has all the methods your TreeStack has, and many more.
public class Demo {
public static void main(String[] args){
Demo instance = new Demo();
instance.init();
}
public void init() {
int size = 0;
inc(size);
System.out.println(size);
}
public int inc(int size){
size++;
return size;
}
}
When I call the code above, the number zero is returned.
Even declaring size as a class attribute instead of a local variable does not solve the problem. I understand that when a method is complete, the corresponding record (containing local variable and such) is popped off of the activation stack. But, if the size variable is declared in the init() method, and then incremented and returned in a separate method (inc()), shouldn't size be equal to 1?
When incrementing you do not assign the value to anything, it increments it, but it does not store it anywhere so the value remains 0, try doing like this.
public class Demo
{
public static void main(String[] args)
{
Demo instance = new Demo();
instance.init();
}
public void init()
{
int size = 0;
size = inc(size);
System.out.println(size);
}
public int inc(int size)
{
size++;
return size;
}
}
or like this
public class Demo
{
public static void main(String[] args)
{
Demo instance = new Demo();
instance.init();
}
public void init()
{
int size = 0;
System.out.println(inc(size));
}
public int inc(int size)
{
size++;
return size;
}
}
size = inc(size);
will solve your problem, since you are not using a public scoped variable.
If you want to make this a bit elegant (at least I think this will be a bit more handy), then you need to declare a variable as a class variable.
I will illustrate this to you:
public class Demo {
int size; //global range variable
public static void main(String[] args){
Demo instance = new Demo();
instance.init();
}
public void init() {
this.size = 0;
inc();
System.out.println(this.size);
}
public void inc(){
this.size++; //will increment your variable evertime you call it
}
}
I want to create a function to change a value in an array, but I don't want to pass the array to the function. Here is the part of the code, data[] array created at another function.
private int[] data;
public static void main(String[] args) {
setPixel(3,2); //I'm not sure at this part?
}
public void setPixel(int i,int x){
data[i] = x; //Is there any possible way to change data[]
}
You should create a class around your main method and instantiate it within main. You then make data a variable of your class and you can access it from within the setPixel() method. This is the proper Object Oriented (OO) way of accomplishing what you're asking.
public class Data {
private int[] data;
public Data(int size) {
data = new int[size];
}
public void setPixel(int i, int x) {
data[i] = x;
}
public static void main(String[] args) {
Data instance = new Data(5);
instance.setPixel(3, 2);
}
}
Here's my answer, which is pretty much like what #zposten provided, but also address's the OP's data[] array created at another function requirement:
public class EncapsulatedArray
{
private final int[] data;
public EncapsulatedArray(final int[] data)
{
this.data = data;
}
public int getPixel(final int i)
{
return data[i];
}
public void setPixel(final int i, final int x)
{
data[i] = x;
}
#Override
public String toString()
{
return Arrays.toString(data);
}
}
To verify and demonstrate, I used:
public class EncapsulatedArrayDemo
{
public static void main(final String[] args)
{
final int[] dataFromElsewhere = { 0, 1, 2, 3 };
final EncapsulatedArray ex = new EncapsulatedArray(dataFromElsewhere);
System.out.println(ex);
ex.setPixel(2, 7 + ex.getPixel(2));
System.out.println(ex);
}
}
and obtained the following to console:
{ 0, 1, 2, 3 }
{ 0, 1, 9, 3 }
There are various reasons why wrapper classes like this (toy) example are useful, but if you are hoping to "protect" the data array from outside changes (i.e. only setPixel(int, int) is allowed to modify values in data) then you'll need something more like #zposten's answer which never lets the data array object escape from the wrapper. If you do need to use a data array created at another function then something like my solution is required - but you'll have to take other steps to ensure that the array isn't fiddled with behind the wrapper's back.
I want each element of an enum to have different variables but I can't reach them.
public class Employee {
public GENERAL[] general = GENERAL.values();
public static void main(String[] args) {
Employee e = new Employee();
e.general[GENERAL.INCOME.ordinal()].salary = 10; //this line doesn't compile
}
enum GENERAL{
INCOME{
public int salary;
public int tips;
},SATIFACTION{
//some variables
},EFFICIENCY{
//some variables
};
}
}
I've tried casting to (GENERAL.INCOME) but it didn't work. Is there a way to do it? If this is not possible, what is the best work around? Thanks in advance.
Try defining variables at enum level rather than individual elements:
public static void main(String[] args) {
MainClass e = new MainClass();
e.general[GENERAL.INCOME.ordinal()].salary = 10; //this line doesn't compile
System.out.println(e.general[GENERAL.INCOME.ordinal()].salary);
}
enum GENERAL{
INCOME(0,0), SATIFACTION(0, 0), EFFICIENCY(0,0);
int salary;
int tips;
GENERAL(int salary, int tips){
this.salary = salary;
this.tips = tips;
}
}
This is because INCOME is an anonymous subclass of GENERAL, it is something like this
static class GENERAL {
public static GENERAL INCOME = new GENERAL() {
public int salary;
public int tips;
};
}
there is no way to access fields of an anonymous class in Java (except reflection)
This is the cleanest way I can do it. I still have an array that I can use to iterate. Each element of the General holds its own variables. Each element has an ordinal to use as the index number.
The problem with this approach is this cannot make use of GENERAL.values(). If a new element is added later, It must be added to the getList() method manually and in the correct order. It is easy to make mistakes when adding new elements to the code.
public class Employee {
public Object general[] = General.getList();
public static void main(String[] args) {
Employee e = new Employee();
General.Income i = (General.Income) e.general[General.Income.ordinal];
i.salary = 10; //eclipse doesn't let me to combine these 2 lines into 1 expressions.
System.out.println(i.salary);
// following lines demonstrates that the salary of the e.general[General.Income.ordinal] is changed. Not just the i.
General.Income t = (General.Income) e.general[General.Income.ordinal];
System.out.println(t.salary);
}
public static class General {
public static Object[] getList() {
Object general[] = { new Income(), new Satisfaction(), new Efficiency() };
return general;
}
public static class Income {
public static final int ordinal = 0;
public int salary;
public int tips;
}
public static class Satisfaction {
public static final int ordinal() {return 1;}//using method instead of int saves memory. (8 bytes I think. Neglettable).
// some variables
}
public static class Efficiency {
public static final int ordinal = 2;
// some variables
}
}
}
If each enumeration would contain a single value, why not use that?
You can even add a method to retrieve some descriptive name:
enum General {
INCOME, SATIFACTION, EFFICIENCY;
int value = 0;
String getName() {
switch(this) {
case INCOME:
return "salary";
case SATIFACTION:
return "etc";
}
}
}
These can be set/get by General.values()[i].value and General.INCOME.value or add setValue(int value) and getValue() methods and make value private.
I think my codes are right, but i do not know why it is not adding elements onto the stack.
Should i create other two stacks in the main?
import java.util.Stack;
public class stacks {
public Stack<Integer> in = new Stack<Integer>();
public Stack<Integer> out = new Stack<Integer>();
public void enqueue(int value){
in.push(value);
}
public int dequeue(){
if (out.isEmpty()){
while(!in.isEmpty()){
out.push(in.pop());
}
}
return out.pop();
}
public static void main(String[] args) {
in.enqueue(10);
in.enqueue(49);
}
}
Your code is absolutely correct. You have missed one small thing.
You are pushing elements in stack 1 during enqueue.
During dequeue, you are popping elements from stack 1 and pushing in stack 2. Then you are popping the top element from stack 2 .
(1).
The stuff that you are missing is. Popping all the elements back from stack 2 and pushing them to stack 1. So, here is what I suggest you to do :
public int dequeue(){
if (out.isEmpty())
{
while(!in.isEmpty())
{
out.push(in.pop());
}
}
int outVar = out.pop();
while(!out.isEmpty())
{
in.push(out.pop());
}
return outVar;
}
(2). In the main method. You do not have to create two different stacks. You just have to create an object of you class Stacks. which would solve the purpose.
public static void main(String[] args) {
Stacks obj = new Stacks();
obj.enqueue(10); // Would enqueue 10 in the Stack 1 of the Object 'obj'
obj.enqueue(49);
System.out.println(obj.dequeue());// Would display the dequeued element.
}
Hope this helps.
Your issue here is that you are trying to make a static reference (from the main) to something that isn't static.
Make the following changes:
public static int dequeue()
public static void enqueue(int value)
A workaround to this would be to make an object oriented stack-queue class and then in a separate class make an instance of that stack-queue class. This would eliminate any static referential issues and also bring your program up to par with today's common object-oriented programming standards. Like so:
import java.util.Stack;
public class stacksTest {
public Stack<Integer> in = new Stack<Integer>();
public Stack<Integer> out = new Stack<Integer>();
public void enqueue(int value){
in.push(value);
}
public int dequeue(){
if (out.isEmpty()){
while(!in.isEmpty()){
out.push(in.pop());
}
}
return out.pop();
}
}
Then make a new class:
public class Test {
public static void main(String[] args) {
stackTest st = new stackTest();
st.enqueue(10);
st.dequeue(10);
}
}