I have some code that sorts a stack using only another stack (it's an interview question). The code itself seems to work. I'd like to implement it using generics, so that any kind of stack is sortable, under the following conditions:
The sort method remains static (I'd like to avoid parameterizing the entire class)
I can use native comparator operators (like <) - I guess the parameterized type needs to implement Comparable.
Is this possible?
Here's the code.
import java.util.Stack;
public class StackSort {
static void sort(Stack<Integer> stack) {
Stack<Integer> tmp = new Stack<Integer>();
for (;;) {
int nswaps = 0;
while (!stack.isEmpty()) {
Integer curr = stack.pop();
if (!stack.isEmpty() && curr < stack.peek()) {
Integer next = stack.pop();
tmp.push(next);
tmp.push(curr);
++nswaps;
} else {
tmp.push(curr);
}
}
while (!tmp.isEmpty()) {
stack.push(tmp.pop());
}
if (nswaps == 0) {
break;
}
}
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(6);
stack.push(4);
stack.push(11);
stack.push(8);
stack.push(7);
stack.push(3);
stack.push(5);
System.out.println(stack);
StackSort.sort(stack);
System.out.println(stack);
}
}
You are on the right way by mentioning Comparable.
Your method can be
static <T extends Comparable<T>>void sort(Stack<T> stack) {
And the comparison curr < stack.peek() replace by
curr.compareTo(stack.peek()) < 0
Using comparator operators on Objects (wrapped primitives or not) is not possible in Java. C++ support such a possibility. However, you can create a workaround by forceing the parameter type to implement Comparable. Your signature should look like this:
public <T extends Comparable<? super T>> static void sort(Stack<T> stack)
And to compare, use compareTo instead of native operators (which is not possible in Java):
obj1.compareTo(obj2)
Related
my code:
public static void spilledOn (Stack<Object> st1,Stack<Object> st2){
while (!st2.isEmpty()){
st1.push(st2.pop());
}
}
public static int findLengthInStack (Stack<Object> st1){
Stack<Object> tmp=new Stack<>();
int count=0;
while (tmp.isEmpty()){
tmp.push(st1.pop());
count++;
}
toolsForAnything.spilledOn(st1, tmp);
return count;
}
when I call this method and I use another type of stack its not working well
(I mean I use Stack<Integer>)
Does anyone have any solution for this ?
(I hope its right that I use with object)
If you really wanted to use this algorithm for some reason, then for a general Stack you would need to declare a type parameter for each method.
// (Really an API would be using super and extends here,
// but let's keep it simple.)
public static <T> void spilledOn (Stack<T> st1,Stack<T> st2){
// ^^^ ^ ^
[...]
// (I'm using a different name (E vs T) here
// just to illustrate that I am declaring two variables.
// Using the same letter would be more conventional.)
public static <E> int findLengthInStack (Stack<E> st1){
// ^^^ ^
Stack<E> tmp=new Stack<>();
// ^
If you want to write the (unnecessary) method to find how many elements are in the stack, you can do it like this:
public class Helper {
private static <T> int findSize(Stack<T> input) {
return input.size();
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(4);
stack.push(9);
System.out.println(findSize(stack));
}
}
Why I said unnecessary? Because you can simply write:
System.out.println(stack.size());
instead of:
System.out.println(findSize(stack));
I am new to Java, and I am trying to implement a sort algorithm which may use the natural order or a given comparator argument.
Say I have a comparable class C with some natural order compareTo, a Comparator subclass ByAltOrder, And I have a Comparator<C> method which returns a new ByAltOrder.
public class C implements Comparable<C> {
... //fields and constructor
public int compareTo(C that) { ... } //natural order
public Comparator<C> altOrder() { //some alternative order
return new ByAltOrder();
}
public class ByAltOrder implements Comparator<C>{
public int compare(C x, C y) { ... }
}
}
I want to write a function which may use the natural order or the alternative order. I know how to write a function that uses either the natural order or the alternative order, but I do not want to write the same code twice with minor differences. Is that possible?
Say I want to write a function returning maximum of a non-empty Array. With natural order it looks like this:
public C max(C[] xs){
res = xs[0];
for (i = 1; i < xs.length; i++) {
if (xs[i].compareTo(res) > 0) {
res = points[i];
}
}
return res;
}
And with Comparator it looks like this and I can pass x.altOrder() as the second argument:
public C max(C[] xs, Comparator c){
res = xs[0];
for (i = 1; i < xs.length; i++) {
if (c.compare(xs[i], res) > 0) {
res = points[i];
}
}
return res;
}
But how I do write a function that incorporates both?
Edit: I got that there is an Arrays.sort in Java, but implementing sort or max is just a toy example for my question about passing Comparators / code reuse / java practice. Perhaps I didn't make it clear about this.
If you truly want to avoid code duplication, you should not implement that operation at all.
Comparator<C> altOrder = …;
C[] array = …;
C naturalMax = Collections.max(Arrays.asList(array));// natural order
C altMax = Collections.max(Arrays.asList(array), altOrder); // alternative order
Note that Arrays.asList does not copy but only wraps the array, so there is no performance consideration preventing to use these methods.
By the way, ByAltOrder and altOrder() should both be static, as they don’t depend on a specific instance of C.
If you want to implement these methods as an exercise, other answers already pointed to it, use delegation and Comparator.naturalOrder().
If you are not using Java 8 or newer, this builtin comparator is not available, but you could work-around it using Collections.reverseOrder(Collections.reverseOrder()) to get a comparator with the same behavior, but, of course, you should replace that with Comparator.naturalOrder() as soon as you migrate to Java 8 or newer.
Technically JB Nizet is right.
This is enough :
public C max(C[] xs){
return max(xs, Comparator.naturalOrder());
}
public C max(C[] xs, Comparator<? super C> c){
C res = xs[0];
for (int i = 1; i < xs.length; i++) {
if (c.compare(xs[i], res) > 0) {
res = points[i];
}
}
return res;
}
Now, concretely, writing these processings seem not relevant
To find the max element (in terms of Comparable/Comparator) of an array, you could just use Arrays.stream().max :
C max = Arrays.stream(xs).max(c);
or
C max = Arrays.stream(xs).max(new ByAltOrder());
By handling the null case if the array is empty (thanks dear Holger), your methods could be as simple as :
public C findMax(C[] xs){
return findMax(xs, Comparator.naturalOrder());
}
public C findMax(C[] xs, Comparator<? super C> c){
return Arrays.stream(xs).max(c).orElse(null);
}
You could do something like this:
public <C extends Comparable<? super C>> C max(C[] xs){
return max(xs, Comparator.naturalOrder());
}
public <C> C max(C[] xs, Comparator<C> c){
C res = xs[0];
for (C x: xs) {
if (c.compare(x, res) > 0) {
res = x;
}
}
return res;
}
I have a programming assignment to make a generic stack in Java and I need to make a deep copy of newNode T. I don't know how to make a method deep Copy that can access its self and output i'`s deep copy. So far, I have this:
public class Stack<T>
{
private T[] data;
private int top;
private int size;
public Stack( )
{ top = -1;
size = 100;
data = (T[])new Object[100];
}
public Stack(int n)
{ top = -1;
size = n;
data = (T[])new Object[n];
}
public boolean push(T newNode)
{ if(top == size-1)
return false; // ** overflow error **
else
{ top = top +1;
data[top] = newNode.deepCopy();
return true; // push operation successful
}
}
public T pop( )
{ int topLocation;
if(top == -1)
return null; // ** underflow error **
else
{ topLocation = top;
top = top -1;
return data[topLocation];
}
}
public void showAll( )
{ for(int i = top; i >= 0; i--)
System.out.println(data[i].toString());
}
}
How can I make the deep copy of newNode. I'm pretty sure I need an interface for the method but past that I`m lost.
Perhaps the most general and straight forward solution would consist in asking the using code to provide the deep-copying routine at construction:
public class Stack<T> {
...
private final Function<T, T> elementCopier;
public Stack<T>(Function<T, T> elementCopier) {
// make sure thy are not passing you a null copier:
this.elementCopier = Objects.requiresNonNull(elementCopier);
...
}
...
public boolean push(T element) {
...
data[top] = elementCopier.apply(element);
...
}
...
}
So for example for a cloneable class type where .clone() is in fact a deepCopy the user code would be like:
Stack<MyElemClz> stack = new Stack<>(x -> x.clone());
// or:
Stack<MyElemClz> stack = new Stack<>(MyElemClz::clone);
...
MyElemClaz elem = ...;
...
stack.push(elem);
If the type is an constant simple object like and String there is no need for clonning, in that case the user would indicate identity lambda x -> x as
the copier:
Stack<String> stack = new Stack<>(x -> x)
If the user insists in making a copy even when the class is a constant you can force it:
Stack<String> stack = new Stack<>(x -> new String(x))
// or
Stack<String> stack = new Stack<>(String::new)
One can use an ObjectOutputStream/ObjectInputStream to make a deep copy.
One would then not store an Object (a reference to changeable fields), but the serialized bytes in the stack.
On to it.
An ObjectOutputStream does a deep copy.
If you want to go with an interface, or you don't like Valentin's approach, you could do this:
interface Copiable<T> {
T deepCopy();
}
public class Stack<T extends Copiable<T>> {
...
}
and then implement the deepCopy method to objects that you put in your stack, i.e.
class A implements Copiable<A> {
#Override
public A deepCopy() {
// ... your copy code here
}
}
Stack<A> stack = new Stack<>();
etc.
I have been trying to implement a Queue using 2 stacks and was able to implement enqueue and dequeue operation correctly. Now i tried implementing getMin in it and got into a bit of problem.
Theory
In theory, to implement a getMin operation, we store two values in stack- The value and minimum till now. So we will be storing these values in this way- {7, 5, 9, 2, 1} ==> {(7,7), (5,5), (9,5), (2,2), (1,1)}. Now if we try to insert 0, first we will check if 0 is less than current min. If true then we will insert it as (0,0) else (0, last_min_value).
My Approach
I created a class name Element like this
class Element<T>{
T element;
T min;
Element(T element, T min){
this.element = element;
this.min = min;
}
}
My Problem
Well code doesn't compile or better to say I don't understand the concept of compareTo at all, when should i use it. I believe i can understand it in a better way, if i directly use it in my program rather than doing some dummy question
import java.util.Stack;
import java.util.LinkedList;
import java.util.Comparator;
class Element<T>{
T element;
T min;
Element(T element, T min){
this.element = element;
this.min = min;
}
}
class MyQueue<T>{
Stack <Element<T>>s_old;
Stack <Element<T>>s_new;
MyQueue(){
s_old = new Stack<Element<T>>();
s_new = new Stack<Element<T>>();
}
void enqueue(T ele){
if(s_old.empty())
s_old.push(new Element<T>(ele,ele));
else{
if(ele.compareTo(s_old.peek().min) < 0) //problem occurs here
s_old.push(new Element<T>(ele, ele));
else
s_old.push(new Element<T>(ele, s_old.peek().min));
}
}
T deque(){
if(s_new.empty()){
while(!s_old.empty()){
s_new.push(s_old.pop());
}
}
return s_new.pop().element;
}
}
class QueueMain{
public static void main(String args[]){
MyQueue <Integer>q = new MyQueue<Integer>();
q.enqueue(1);
q.enqueue(2);
//System.out.println(q.s_old);
System.out.println(q.deque());
}
}
The problem is quite simple:
In java we have 2 ways to compare an object.
The compared class can either implement the Comparable Interface or use a Comparator.
Here is how you can make the above code work with the Comparable interface:
Comparable
class Element<T extends Comparable<T>> implements Comparable<Element<T>>
{
T element;
T min;
Element(T element, T min)
{
this.element = element;
this.min = min;
}
#Override
public int compareTo(Element<T> ele)
{
int elementCompareResult = ele.element.compareTo(element);
if (elementCompareResult == 0){
// element is the same, Compare by min
return min.compareTo(ele.min);
}
return elementCompareResult;
}
}
Notice how I demand that T will extend Comparable himself, otherwise I would have no way of compering it.
Edit:
Also, the myQueue class looks like this now:
class MyQueue<T extends Comparable<T>>
Comperator
Now lets say I dont want to ask for a T that implements comparable.
I could ask for a Comparator in the constructor like so:
class MyQueue<T>
{
Stack<Element<T>> s_old;
Stack<Element<T>> s_new;
Comparator<T> comparator;
MyQueue(Comparator<T> comparator)
{
s_old = new Stack<Element<T>>();
s_new = new Stack<Element<T>>();
this.comparator = comparator;
}
void enqueue(T ele)
{
if (s_old.empty())
{
s_old.push(new Element<T>(ele, ele));
}
else
{
if (comparator.compare(ele, s_old.peek().min) < 0) //problem occurs here
{
s_old.push(new Element<T>(ele, ele));
}
else
{
s_old.push(new Element<T>(ele, s_old.peek().min));
}
}
}
T deque()
{
if (s_new.empty())
{
while (!s_old.empty())
{
s_new.push(s_old.pop());
}
}
return s_new.pop().element;
}
}
Now I will need to create a comparator for by T.
Lets say my T is an Integer:
class MyAwesomeIntegerComparator implements Comparator<Integer>{
#Override
public int compare(Integer first, Integer second)
{
return first - second;
}
}
Now using this:
public static void main(String args[])
{
MyQueue<Integer> q = new MyQueue<Integer>(new MyAwesomeIntegerComparator());
q.enqueue(1);
q.enqueue(2);
//System.out.println(q.s_old);
System.out.println(q.deque());
}
Summery
To sum up:
In java you can either compare by making the desired class compareable
Or by making it a separated Comperable just for it and then use it when needed.
Why would I ever need a Comperable ?
Lets say I have a class cow.
Sometimes I want to compare it by amount of milk it gives.
Sometime by wight.
I'l make a method that accepts any Cow comperator and it wont care what comparator its using.
For example, the Arrays.sort() method does exactly that.
sort(T[] a, Comparator<? super T> c)
How this helps.
For my data structures class our homework is to create a generic heap ADT. In the siftUp() method I need to do comparison and if the parent is smaller I need to do a swap. The problem I am having is that the comparison operators are not valid on generic types. I believe I need to use the Comparable interface but from what I read it’s not a good idea to use with Arrays. I have also search this site and I have found good information that relates to this post none of them helped me find the solution
I removed some of the code that wasn’t relevant
Thanks
public class HeapQueue<E> implements Cloneable {
private int highest;
private Integer manyItems;
private E[] data;
public HeapQueue(int a_highest) {
data = (E[]) new Object[10];
highest = a_highest;
}
public void add(E item, int priority) {
// check to see is priority value is within range
if(priority < 0 || priority > highest) {
throw new IllegalArgumentException
("Priority value is out of range: " + priority);
}
// increase the heaps capacity if array is out of space
if(manyItems == data.length)
ensureCapacity();
manyItems++;
data[manyItems - 1] = item;
siftUp(manyItems - 1);
}
private void siftUp(int nodeIndex) {
int parentIndex;
E tmp;
if (nodeIndex != 0) {
parentIndex = parent(nodeIndex);
if (data[parentIndex] < data[nodeIndex]) { <-- problem ****
tmp = data[parentIndex];
data[parentIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftUp(parentIndex);
}
}
}
private int parent(int nodeIndex) {
return (nodeIndex - 1) / 2;
}
}
Technically you're using the comparable interface on on item, not an array. One item in the array specifically. I think the best solution here is to accept, in the constructor, a Comparator that the user can pass to compare his generic objects.
Comparator<E> comparator;
public HeapQueue(int a_highest, Comparator<E> compare)
{
this.comparator = compare;
Then, you would store that comparator in a member function and use
if (comparator.compare(data[parentIndex],data[nodeIndex]) < 0)
In place of the less than operator.
If I am reading this right, E simply needs to extend Comparable and then your problem line becomes...
if (data[parentIndex].compareTo(ata[nodeIndex]) < 0)
This is not breaking any bet-practice rules that I know of.