Using Stacks to pop and push a method or action - java

So for a project for Uni I have a LinkedList with methods such as insert, delete, sort, reverse, etc. Part of the assignment is the implementation of an Undo button using Stacks.
is to have it so that every time i call a method, i push it's counter. For example I insert something, so i push a delete of that something. However I'm not sure if you can do that with a stack? If I understand stacks correctly aren't they primitive data types in an Array?
Sorry if the answer is obvious, but I really did do research on this and am still quite blank on the answer so any help is super appreciated!

This is a stack. Your assingment seems to follow the Command Pattern. So you would "record" each action (like add, delete, ...) in a LIFO (Last In - First Out)-stack. When you undo an action, you simply "reverse" the topmost command of the stack. How to "reverse" the operation exactly depends on the operation in question and is for you to figure out.

I think you are missing some aspects of a stack data structure.
A stack is a last in, first out. What this means is that you have some root Node that contains whatever the data type you need to hold is, and then a reference to the next Node. So for the last in, you would go to the very last Node in your linked list, and add it at the end. For removing, you would find the last Node, and remove the reference to it from the previous.
I don't think you've done enough research then, read up on linked lists, and the data structure stack. If you have any more questions, please ask, but try to find the answers yourself first.

Related

How can I move a value to the bottom of a stack rather than the top?

(This is using the java.util.Stack)
In my code I got a value, lets say a string "1" and I want to put that at the bottom of this stack of numbers.
"4"
"3"
"2"
Now the methods I have for the java.util.Stack don't actually come with a way I can just send my value of "1" to the bottom of this stack, they instead only let me push the value to the top of the stack which isn't any good to me.
Is there a way I can send "1" to the bottom of this stack?
You can do it like this. The add method allows you to put a value anywhere in the stack. But you're basically subverting the nature of the stack. Stacks are meant to be LIFO (last in, first out). You may want to rethink your design if this is what you want to do. There are various Collection implementations from which you can choose. Check the API and read the documentation to see which one best suits your needs.
Stack<Integer> stack = new Stack<>();
stack.push(4);
stack.push(3);
stack.push(2);
stack.add(0,1);
while(!stack.isEmpty()) {
System.out.println(stack.pop());
}
prints
2
3
4
1
It's a stack, a last-in-first-out data structure. Fundamentally, you can't add to the bottom unless it's empty.
You may want to use a different data type, I think java.util.Deque would work for you.
You actually can't. You can only push and pop the top element of the stack. If you wish to access your data structure both by top and bottom at the same time, you should use another data structure. Try using the LinkedList class instead which offers what you want to do.

How does List.add(index,element) work internally in Java?

As mentioned in Java API Doc and this post, the list.add(index,element) results in the given element being added at the given index. In the process, the subsequent list items are shifted by one position to the right (by adding one to their indices as mentioned in the API Doc)
My question is how does this happen practically?
Suppose we have an ArrayList containing 100 elements and we say add(0, 6), now how would the API accomplish this action, given the fact that the underlying Data Structure is an array?
More specifically: Would all the existing 100 elements be copied to its immediate right location? Or is there a more efficient way by which this is handled?
For an ArrayList the elements will indeed be moved up. This is just linear memory access so actually surprisingly fast.
Inserting at the front is faster with an ArrayDeque, which uses a cyclic buffer. That is, not only does it keep track of the last element index, but also the first and the array wraps around. Unfortunately, ArrayDeque does not implement List which it arguably should do.
The very slow LinkedList can remove the first element quickly but is generally very slow.
The source code for all of these classes is freely available and not too complex.

How to get a object with a special id out of the stack?

In my cardgame-project, I simulate a cardpile with a stack. Each card of the pile/stack has an unique identifier.
Now I want to take the object with the specific identifier out of the stack.
Is there an efficient option to realize it? First I thought about an iterator which will iterate over the stack... but it's not an optimum solution if I have many cards on the stack.
You may refer to the "stack of cards" as a stack, but that should not be confused with a stack data structure. I'll recommend two data structures for your card objects in your game:
A List to keep some form of ordering (so that you know in which order the cards are). An ArrayList will work well here.
A HashHap for quick retrieval (remember, a Map usually loses its ordering).
As the SAME card will be present in both data structures, you won't be using that much more memory, but will have the advantages of both data structures (quick lookup and ordering). You'll have to handle a bit of housekeeping, but that will be expected.
You might also keep a Map<Key, Card> to keep track of cards by their unique ID (Key might be String, Integer, etc). Then you could call remove(Object), which Stack inherits from Vector, passing in the Card you wanted removed.
This is assuming you're constrained to the Stack data structure, which you may not be (see other answers).
Well, that's how a stack works. To get some other than the top item from a stack, you have to pop all items and push them on another stack until you found your item. Then you have to pop all the items from the other stack and push them back to the original stack.
That's what you'd do if you were looking for a card manually, too.
Stack is LIFO and you have to pop items until you find needed one.Then push popped items back.You should use something like map to get an item with ID easier.

the undo and redo implementation in Java

I want to ask a question about List in Java.
It is easy to implement delete,add and search an element in a list. But how to implement the undo and redo of a list in Java?
can anyone help me on this?
You might be looking to implement a Command Design Pattern for this. A decent simplified example for List can be found here http://www.algosome.com/articles/implementing-undo-redo-java.html
I guess you want to undo and redo the operations like delete and add on a list.
Just use another list with indexing capabilities for Undo and Redo, e.g. an ArrayList:
Each time an add(element) or delete(element) to the original list really changes that list, you put the element at the end of your undo-list.
Then when you want to undo the operations, you just move through the undo-list: If the element in the undo-list is not in the original list, add it, if it is present in the original list, remove it.
If you want to use your undo-list for redo, too, then don't remove the elements you just "undid" from the undo-list, but rather move through the undo-list via an index. Then you can move through the undo-list in both direction and hence undo and redo your operations.
You mean like delete item from list and undo it? You can easily create new class for a list and define properties like: last performed action + store the origin value (and possibly index) of the effected item. The same for redo (at least for one step in redo and undo). If you don't care about order of the items (or you can order them easily), then define list of last performed actions and list of origin values. So for example:
lastAction[0]="delete";
lastElement[0] = 1; // means you deleted 1 from the list
That's the first and dummy idea how to that. Perhaps there are some issues to consider...
You need binding to do that.
To me this is the most efficient way to do that. This question at SO can give you some hints regarding from where to start.

Java TreeNode: How to prevent getChildCount from doing expensive operation?

I'm writing a Java Tree in which tree nodes could have children that take a long time to compute (in this case, it's a file system, where there may be network timeouts that prevent getting a list of files from an attached drive).
The problem I'm finding is this:
getChildCount() is called before the user specifically requests opening a particular branch of the tree. I believe this is done so the JTree knows whether to show a + icon next to the node.
An accurate count of children from getChildCount() would need to perform the potentially expensive operation
If I fake the value of getChildCount(), the tree only allocates space for that many child nodes before asking for an enumeration of the children. (If I return '1', I'll only see 1 child listed, despite that there are more)
The enumeration of the children can be expensive and time-consuming, I'm okay with that. But I'm not okay with getChildCount() needing to know the exact number of children.
Any way I can work around this?
Added: The other problem is that if one of the nodes represents a floppy drive (how archaic!), the drive will be polled before the user asks for its files; if there's no disk in the drive, this results in a system error.
Update: Unfortunately, implementing the TreeWillExpand listener isn't the solution. That can allow you to veto an expansion, but the number of nodes shown is still restricted by the value returned by TreeNode.getChildCount().
http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html#data
scroll a little down, there is the exact tutorial on how to create lazy loading nodes for the jtree, complete with examples and documentation
I'm not sure if it's entirely applicable, but I recently worked around problems with a slow tree by pre-computing the answers to methods that would normally require going through the list of children. I only recompute them when children are added or removed or updated. In my case, some of the methods would have had to go recursively down the tree to figure out things like 'how many bytes are stored' for each node.
If you need a lot of access to a particular feature of your data structure that is expensive to compute, it may make sense to pre-compute it.
In the case of TreeNodes, this means that your TreeNodes would have to store their Child count. To explain it a bit more in detail: when you create a node n0 this node has a childcount (cc) of 0. When you add a node n1 as a child of this one, you n1.cc + cc++.
The tricky bit is the remove operation. You have to keep backlinks to parents and go up the hierarchy to subtract the cc of your current node.
In case you just want to have the a hasChildren feature for your nodes or override getChildCount, a boolean might be enough and would not force you to go up the whole hierarchy in case of removal. Or you could remove the backlinks and just say that you lose precision on remove operations. The TreeNode interface actually doesn't force you to provide a remove operation, but you probably want one anyway.
Well, that's the deal. In order to come up with precomputed precise values, you will have to keep backlinks of some sorts. If you don't you'd better call your method hasHadChildren or the more amusing isVirgin.
There are a few parts to the solution:
Like Lorenzo Boccaccia said, use the TreeWillExpandListener
Also, need to call nodesWereInserted on the tree, so the proper number of nodes will be displayed. See this code
I have determined that if you don't know the child count, TreeNode.getChildCount() needs to return at least 1 (it can't return 0)

Categories