Generic method with stack - java

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));

Related

Is there a class in java similar to StringBuilder with the only difference that it has a fixed length?

Something like this:
MyFixedLengthStringBuilder sb = new MyFixedLengthStringBuilder(2);
sb.append("123"); // <=== throws ArrayIndexOfOutBoundsException!
The rest would be exactly the same. Basically I need a StringBuilder that can never grow.
I see that StringBuilder is final so it can not be extended. Delegation sounds like my only path here. Do you see any other hack/idea/solution for my need?
You could so something like this. You would still have to have some overloaded methods to handle different argument counts and types but it wouldn't have to be a full delegation. This is just a simple example. It could be worked into a class. EDIT: Modified to handle most methods.
interface TriConsumer<T,R,S> {
public void accept(T t, R r, S s);
}
public class StringBuilderSol {
static int size = 20;
static StringBuilder sb = new StringBuilder(size);
public static void main(String[] args) {
execute(sb::append, "This is fun!");
System.out.println(sb);
execute(sb::append, "Java!");
System.out.println(sb);
execute(sb::delete, 0,3);
execute(sb::replace,0,1,"I");
execute(sb::insert, 1, " like ");
execute(sb::delete, 7,15);
System.out.println(sb);
execute(sb::append, "time to crash");
}
public static <T> void execute(Consumer<T> con,
T v) {
con.accept(v);
checkLength();
}
public static <T,R> void execute(
BiConsumer<T, R> biCon,
T index, R val) {
biCon.accept(index, val);
checkLength();
}
public static <T,R,S> void execute(
TriConsumer<T, R, S> triCon,
T index, R arg1, S arg2) {
triCon.accept(index, arg1, arg2);
checkLength();
}
public static void checkLength() {
if (sb.length() > size) {
throw new IndexOutOfBoundsException();
}
}
}
Prints
This is fun!
This is fun!Java!
I like Java!
Exception in thread "main" java.lang.IndexOutOfBoundsException
at stackOverflow.StringBuilderSol.checkLength(StringBuilderSol.java:50)
at stackOverflow.StringBuilderSol.execute(StringBuilderSol.java:32)
at stackOverflow.StringBuilderSol.main(StringBuilderSol.java:25)
Another option (but one that has its own problems) is to set up a timer to periodically check the size of the StringBuilder.
If I could create my own class, it would go something like this and based on requirements more things could be added
public class MyFixedLengthStringBuilder {
StringBuilder sb;
int size;
public MyFixedLengthStringBuilder(int size) {
if(size < 0)
throw new IllegalArgumentException();
this.size = size;
sb = new StringBuilder(size);
}
public void append(String str) {
sb.append(str);
if(sb.length() > size) {
sb.setLength(size);
throw new ArrayIndexOutOfBoundsException();
}
}
}
First of all, the customer requirement is insufficiently specified: Are they requesting a class that is assignment-compatible with StringBuilder or are they simply requesting a class with a specific functionality?
The former is technically impossible, since StringBuilder is declared as final, thus any variable of type StringBuilder will always have the same behavior.
The latter allows you to specify your own new class with your own methods. As for the requirement, the customer likely specified "I just need everything from StringBuilder.", because they didn't bother to actually check what they need precisely. I think it is quite likely that you will be able to craft a class with just a few methods fit for the customer's needs, if you both invest some work into narrowing down the requirement.
And yes, as you already mentioned, in this case it is a good idea to use a composition with the original StringBuilder class.
As you were asking for a hack, you could theoretically write your own implementation of java.lang.StringBuilder and provide a custom ClassLoader that loads your implementation instead of the standard java one. I hope it is obvious that this is not a good practice, though.

How can I make this code work with generics?

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)

how do we know which method (java.class) has called the current one

Example: If I have two classes: A and B. both class can call a method in C (example: the init() method)
From C, how do we know where the call is from (from Class A or Class B) ?
To do it right, you should provide C's method with that information, for example via an enum or class parameter:
public void init(Object otherArg, Class<?> caller) {
...
}
or
public void init(Object otherArg, CallerEnum caller) {
...
}
But if you don't care, there is another way using the stack trace. Have a look at Get current stack trace in Java and use the second StackTraceElement from the top of the stack to get the method that called the current one.
This may be useful:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
you can use this to get the stack trace of the current thread in a StackTraceElement array where the first element of the array is the most recent method invocation sequence on the stack
provided the returned array is of non-zero length.
StackTraceElement has methods like getClassName, getMethodName, etc., which one can use to find the caller class name or method name.
Taken from somewhere of the web...
private static final int CLIENT_CODE_STACK_INDEX;
static {
// Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
int i = 0;
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
i++;
if (ste.getClassName().equals(MyClass.class.getName())) {
break;
}
}
CLIENT_CODE_STACK_INDEX = i;
}
public static String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX].getMethodName();
}
public static String getCallerMethodName() {
return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX+1].getMethodName();
}
I found an easier solution (for me :D )
public <T> void init(Class<T> clazz) {
if (!clazz.getSimpleName().equals("MyClassName")) {
// do something
}else{
// do something
}
}

isEven in another method

Something is very wrong here...
public class evenness {
public static Boolean isEven (Integer i) {
return (i % 2) == 0;
}
public static void main(String[] args) {
if (isEven(Integer i)) { //something wrong on this line.
System.out.print("YAY!");
}
}
}
Please help me sort it out!
You are supposed to give an Integer argument to the function isEven, for example 3 or 125.
I'm pretty sure that your IDE is telling you that it can't find the variable Integer. So you need to give a variable. The argument type is only required in the method definition.
For example:
int number = 4;
if(isEven(number)){
...
}
or more directly
if(isEven(4)){
...
}
Change
if (isEven(Integer i)) {
to something like
int i = 5;
if (isEven(i)) {
or
if (isEven(5)) {
You need to pass an integer to the method.
Just provide an argument where you call your method in main();
public class evenness {
public static Boolean isEven (Integer i) {
return (i % 2) == 0;
}
public static void main(String[] args) {
if (isEven(36)) { //something wrong on this line.
System.out.print("YAY!");
}
}
}
Following Java coding convention by changing the class name to Evenness.
public class Evenness
The method isEven(...) should accept int and return boolean. Both are primitive data types. This will make the program runs faster than using their wrappers. A wrapper is a reference type (object) that wraps a primitive type. For example, Integer wraps int and Boolean wraps boolean.
public static boolean isEven (int i) {
Send an argument to isEven(...)
if (isEven(2)) { // this line is now OK.

Comparable type Sorting in a Vector int or String

In this I am trying to sort out the intV and stringV using this getSmallestValue method. Tried different ideas but does not seems to be working. Anyone have any bright ideas how to implement this getSmallestValue method?
public class test {
public static Comparable getSmallestValue(Vector<Comparable> a) {
Comparator com = Collections.reverseOrder();
Collections.sort(a, com);
return (Comparable) a;
}
public static void main(String[] args) {
Vector<Comparable> intV = new Vector<Comparable>();
intV.add(new Integer(-1));
intV.add(new Integer(56));
intV.add(new Integer(-100));
int smallestInt = (Integer) getSmallestValue(intV);
System.out.println(smallestInt);
Vector<Comparable> stringV = new Vector<Comparable>();
stringV.add("testing");
stringV.add("Pti");
stringV.add("semesterGoes");
String smallestString = (String) getSmallestValue(stringV);
System.out.println(smallestString);
}
}
Welcome to StackOverflow.
Your basic problem is that you have tried to turn a Vector into an Integer which you cannot do.
What is likely to be more useful is to use the first element of the vector.
I would suggest you
use List instead of Vector.
I wouldn't use manual wrapping
define the getSmallestValue using generics to avoid confusion.
Here are two ways you could implement this method.
public static <N extends Comparable<N>> N getSmallestValue(List<N> a) {
Collections.sort(a);
return a.get(0);
}
public static <N extends Comparable<N>> N getSmallestValue2(List<N> a) {
return Collections.min(a);
}
List<Integer> ints = Arrays.asList(-1, 56, -100);
int min = getSmallestValue(ints);
// or
int min = Collections.min(ints);
Use Collections.min().You can check out the source if you you want to know how it's implemented.
Vector<Integer> v=new Vector<Integer>();
v.add(22);v.add(33);
System.out.println(Collections.min(v));

Categories

Resources