I don´t know how to push a tree into a Stack - java

Hi I am working with the Stack class in java, the problem that I have is that in this Stack I want to insert (to push) elements of type String, but i also want to insert a tree, the code is the following:
public static void Expression(Stack<String> exp)
{
boolean error = false;
String leftExp,rightExp = "";
Stack<String> stackOp = new Stack<String>();
while(!exp.empty() && (error == false))
{
switch(elementType(exp.peek())){
case 'I':
error = true;
break;
case 'O':
if(stackOp.size() < 2)
error = true;
else
{
rightExp = stackOp.pop();
leftExp = stackOp.pop();
Tree subTree = new Tree();
subTree.insertNode(exp.peek());
subTree.insertNode(rightExp);
subTree.insertNode(leftExp);
stackOp.push(subTree);//here is were I have the mistake
}
break;
default:
stackOp.push(exp.peek());
}
}
}
public static char elementType(String car){
char c = 'Z';
if(car.equals("("))
c = 'I';
else if(car.equals(")"))
c = 'D';
else if(car.equals("+") || car.equals("-") || car.equals("*") || car.equals("/"))
c = 'O';
return c;
}
This code basically transforms a math expression into a binary tree, for this I need an input, which is the expression, an output which is the binary tree, and another local stack that contains variables, numbers, and subtrees. But how can i make a Stack that contains elements of different types?

Create a class that can hold anything you want to put on the stack -- I think using a string to designate your operation is a bit clumsy, but suit yourself. If you have a class that is StackElement, it can contain a type indicator (look into Java enums) and methods to do or obtain whatever you want.
You could define StackElement to contain a reference to one of several types, then also define all the methods of all the types it might contain; the ones that apply would be pass-throughs (if the type is an operation, a pass-through for getOperationType()), and the others would throw illegalOperationException, or something. So if you try to call getOperationType() on a value, it throws an exception, same for calling getValue() on an operation, etc.
A nice thing about doing it this way is that you do not have to do any instanceof testing of the types you have stored. You can declare your FILO queue to hold StackElement objects, create them with the types you want, and use them, all without instanceof or otherwise breaking OO style.
public class StackElement
{
private StackElementType type;
private StackOperation operation;
private StackValue value;
public StackElementType getType() { return type; }
public StackOperation getOperation()
{
switch (type)
{
case StackElementType.OPERATION: return operation;
default: throw IllegalOperationException
("getOperation() on type " + type.toString());
}
}
public StackValue getValue()
{
switch (type)
{
case StackElementType.VALUE: return value;
default: throw IllegalOperationException
("getValue on type " + type.toString());
}
}
}

Related

Method returns a value but the compiler indicates a missing return

I'm returning the instance of my sort classes that all inherit from the TestTimes class.
However, when I return the instance, I'm getting an error, saying I need to return a result of type TestTimes.
It also says this: "missing 'default:' on 'switch' has been suppressed," which is perhaps related to this problem?
public TestTimes runSort(SortType sortType, ArrayType arrayType, int arraySize, int numberOfTimes) {
switch (sortType) {
case BubbleSort :
BubbleSort bs = new BubbleSort();
switch (arrayType) {
case Increasing :
for(int i = 0; i < numberOfTimes; i++)
bs.sort(createArray(arrayType, arraySize));
break;
case Random :
for(int i = 0; i < numberOfTimes; i++)
bs.sort(createArray(arrayType,arraySize));
break;
}
return bs;
case InsertionSort:
InsertionSort is = new InsertionSort();
switch (arrayType) {
case Increasing:
for(int i = 0; i < numberOfTimes; i++)
is.sort(createArray(arrayType, arraySize));
break;
case Random:
for(int i = 0; i < numberOfTimes; i++)
is.sort(createArray(arrayType, arraySize));
break;
}
return is;
}
}
All of the "logical" paths through a method need to return based on the method's contract. In your case, you have a switch statement, but only defined two explicit cases and no default. This is like having an if-else if without an else -- what if you don't meet either condition?
Simplified, you have something like this:
public SomeType doSomething(SomeEnum enumValue) {
switch(enumValue) {
case SomeEnum.FOO:
// do something
return something;
case SomeEnum.BAR:
// ...
return something;
}
// But what if enumValue is neither? We end up here ... with no return!
}
What if your enum isn't either of those values?
This is what your compiler is trying to tell you. Now, if these are the only supported values, you might want to throw an exception like an IllegalArgumentException to indicate a bad input. Or perhaps you want to return a null or a different indicator.
This is why it's not good to suppress the compiler warning related to the switch missing the default case -- because it often indicates, as you have here, that you have a missing path in your logic. Also, what if you at some point add a new type of search to your enum? Even though you only support Bubble and Insertion sort now, maybe you'll want to support a Radix sort later, but there will be no handling in the method for that yet.
You should add a default case to your switch, or add an explicit return or throws at the bottom of your method to handle the fall-through cases that you don't explicitly support
For example, with default:
switch(sortType) {
case BubbleSort:
return ...;
case InsertionSort:
return ...;
default:
throw new IllegalArgumentException("Only BubbleSort and InsertionSort supported!");
}
Or, alternatively, with an explicit return:
public TestTimes runSort (...) {
switch(sortType) {
case BubbleSort:
return ...;
case InsertionSort:
return ...;
}
// we'll end up here with any other sort type...
return null; // or throw new Exception(...) etc
}

Efficiently Check Multiple Conditions [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I've got a situation in which I need to check multiple conditions, where every combination has a different outcome. In my specific condition, I've got 2 variables, which are enum types, that can each be 2 different values.
enum Enum1
{
COND_1,
COND_2
}
enum EnumA
{
COND_A,
COND_B
}
Enum1 var1;
EnumA varA;
This gives me 4 possible conditions, which requires 4 different outcomes. I've come up with a few different ways of doing this, either using if statements or switch statements:
if(var1 == Enum1.COND_1 && varA == EnumA.COND_A)
{
// Code
}
else if(var1 == Enum1.COND_1 && varA == EnumA.COND_B)
{
// Code
}
else if(var1 == Enum1.COND_2 && varA == EnumA.COND_A)
{
// Code
}
else if(var1 == Enum1.COND_2 && varA == EnumA.COND_B)
{
// Code
}
Or:
switch(var1)
{
case COND_1:
switch(varA)
{
case COND_A:
// Code
break;
case COND_B:
// Code
break;
}
break;
case COND_2:
switch(varA)
{
case COND_A:
// Code
break;
case COND_B:
// Code
break;
}
break;
}
I've thought of others, but don't want to fill this up with code :P I'd like to know what the best way to do this is. I think the switch is a bit easier to read, but the ifs are shorter. I think it'd be really cool if switches could have multiple conditions, but I haven't heard of it. This also begs the question: what's the best way to do this with an arbitrary number of variables and possible values?
For your small use case I would probably go for nested if statements. But if you have plenty of enum constants, perhaps a pattern using streams could make your code easier to read and maintain (for a small performance penalty). You could solve it using a stream like this:
Stream.of(new Conditional(COND_1, COND_A, () -> {/* do something */}),
new Conditional(COND_1, COND_B, () -> {/* do something */}),
new Conditional(COND_2, COND_A, () -> {/* do something */}),
new Conditional(COND_2, COND_B, () -> {/* do something */}))
.filter(x -> x.test(var1, varA))
.findAny()
.ifPresent(Conditional::run);
That would require a supporting class:
class Conditional implements BiPredicate<Enum1, EnumA>, Runnable
{
private final Enum1 var1;
private final EnumA varA;
private final Runnable runnable;
public Conditional(Enum1 var1, EnumA varA, Runnable runnable) {
this.var1 = var1;
this.varA = varA;
this.runnable = runnable;
}
#Override
public boolean test(Enum1 enum1, EnumA enumA) {
return var1 == enum1 && varA == enumA;
}
#Override
public void run() {
runnable.run();
}
}
Performance differences are probably negligible here, so I would focus on shortness and readability. So I would just simplify the if's a bit by using temporary variables:
boolean is_1 = (var1 == Enum1.COND_1);
boolean is_A = (varA == EnumA.COND_A);
if(is_1 && is_A)
{
// Code
}
else if(is_1 && !is_A)
{
// Code
}
else if(!is_1 && is_A)
{
// Code
}
else if(!is_1 && !is_A)
{
// Code
}
I prefer the if variant without nesting, since it is short and you have all the conditions in one line.
When stopping through the code during debugging, it can get tedious though, since you have to step over all preceding conditions, which is O(n). When executing the code, this shouldn't matter since the compiler will probably optimize the code.
There is no obvious best way, so you will have to experiment a bit.
I definitely prefer the flat version, it could just use a little less duplication:
// If you can't make the variables final, make some final copies
final Enum1 var1 = Enum1.COND_2;
final EnumA varA = EnumA.COND_B;
class Tester { // You could also make an anonymous BiPredicate<Enum1, EnumA>
boolean t(Enum1 v1, EnumA vA) {
return var1 == v1 && varA == vA;
}
};
Tester tes = new Tester();
if (tes.t(Enum1.COND_1, EnumA.COND_A)) {
// code
} else if (tes.t(Enum1.COND_1, EnumA.COND_B)) {
// code
} else if (tes.t(Enum1.COND_2, EnumA.COND_A)) {
// code
} else if (tes.t(Enum1.COND_2, EnumA.COND_B)) {
// code
}
Run it here. You could maybe make it even shorter and less redundant by doing a static import of the enums to avoid mentioning the enum names, e.g. tes.t(COND_1, COND_B). Or if you're willing to give up some compile time safety you can pass a string which gets converted to the two enum values, e.g. tes.t("COND_1 COND_A") (the implementation is left to the reader).
Maybe crazy idea but you could construct an int or a byte using the flags and use it in a single switch.
private int getIntegerStateForConditions(boolean... conditions ){
int state = 0;
int position = 0;
for(boolean condition: conditions){
if(condition){
state = state || (1 << position++);
}
}
return state;
}
...
switch(getIntegerStateForCondition((var1 == Enum1.COND_1), (var2 == EnumA.COND_A)){
case 0: ... //both condition false
case 1: ... //first condition true second false
case 2: ... //first false, second true ...
}
...
I think this is very far from being clean code but it looks better.
If I were you I would rely on bit flags in order to have only one byte (as you have only 4 use cases) to deal with and use a switch statement on this byte to manage all your use cases.
Something like this:
private static final int COND_2 = 1;
private static final int COND_B = 2;
private byte value;
public void setValue(Enum1 enum1) {
if (enum1 == Enum1.COND_1) {
this.value &= ~COND_2;
} else {
this.value |= COND_2;
}
}
public void setValue(EnumA enumA) {
if (enumA == EnumA.COND_A) {
this.value &= ~COND_B;
} else {
this.value |= COND_B;
}
}
public Enum1 getEnum1() {
return (this.value & COND_2) == COND_2 ? Enum1.COND_2 : Enum1.COND_1;
}
public EnumA getEnumA() {
return (this.value & COND_B) == COND_B ? EnumA.COND_B : EnumA.COND_A;
}
Then your tests would be:
switch (value) {
case 0 :
// 1-A;
break;
case 1 :
// 2-A;
break;
case 2 :
// 1-B;
break;
case 3 :
// 2-B;
break;
}
I would personally prefer this:
if(understandableNameInContextName1(var1, varA))
{
// Code
}
else if(understandableNameInContextName2(var1, varA))
{
// Code
}
else if(understandableNameInContextName3(var1, varA))
{
// Code
}
else if(understandableNameInContextName4(var1, varA))
{
// Code
}
private boolean understandableNameInContextName1(Object var1, Object varA){
return (var1 == Enum1.COND_1 && varA == EnumA.COND_A);
}
private boolean understandableNameInContextName2(Object var1, Object varA){
return (var1 == Enum1.COND_1 && varA == EnumA.COND_B);
}
private boolean understandableNameInContextName3(Object var1, Object varA){
return (var1 == Enum1.COND_2 && varA == EnumA.COND_A);
}
private boolean understandableNameInContextName4(Object var1, Object varA){
return (var1 == Enum1.COND_2 && varA == EnumA.COND_B);
}
And the names of the methods could be like, isOrderShippedAndDelivered(), isRequestSendAndAckRecieved().
The reason is that this is going to make the code a lot more readable.
Unless you have data that leads you back to these if statement there is not going to be much gain optimizing these.
See:
https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
Kind of depends on the complexity of the code and number of combinations but another option is a dictionary with the key comprising a Tuple of your enumerations and a value of a delegate to the code.

Converting from different values to Enum value

My application gets external data which needs to be translated to a corresponding Enum value. This was my first approach:
public enum Side {
LEFT,
RIGHT;
public static Side fromByte(Byte b) throws Exception {
switch(b)
{
case 'l':
return LEFT;
case 'r':
return RIGHT;
default:
throw new Exception("not a valid byte");
}
}
}
Is this okay, or is there a more idiomatic way to do this?
Note: Ignore the byte to char comparison and the very generic exception throw, i will look into that later - especially the char and byte type conversion. Seems to be a bigger deal than i originally anticipated.
I usually go for something like this,
public enum Side
{
LEFT('l'),
RIGHT('r');
private byte byteValue;
private Side(byte byteValue)
{
this.byteValue = byteValue;
}
public byte getByteValue()
{
return byteValue;
}
public static Side findByByteValue(byte value)
{
for(Side side : values())
{
if(side.byteValue == value)
{
return side;
}
}
return null;
}
}
Approach looks good. But if there is a possibility of a large of cases then consider using map(implementation can be HashMap in your case) as it will be more readable and lesser code.

Doing Trinary logic with java.lang.Boolean and switch

java.lang.Boolean is perfect to handle trinary logic, because it can exactly have three states: Boolean.TRUE (it is the case that), Boolean.FALSE (it is not the case that) and null (we don't know what the case is). It would be a nice design to handle this using switch statements, eg. in this constructor:
public class URN {
private String value = null;
public URN (String value, Boolean mode){
switch (mode){
case TRUE:
if(!isValidURN(value))
throw new MalformedURLException("The string could not be parsed.");
this.value = value;
break;
case FALSE:
this.value = value.concat(checkByteFor(value));
break;
case null:
if(isValidURN(value))
this.value = value;
else
this.value = value.concat(checkByteFor(value));
break;
}
return;
}
Unluckily, Java doesn't allow that, complaining "Cannot switch on a value of type Boolean." Implementing this results in an obfuscated control flow and unnice code:
public URN (String value, Boolean mode){
Boolean valid = null;
if (!Boolean.FALSE.equals(mode)){
valid = isValidURN(value);
if (Boolean.TRUE.equals(mode) && !valid)
throw new MalformedURLException("The string could not be parsed.");
if(Boolean.TRUE.equals(valid)) {
this.value = value;
return;
} }
this.value = value.concat(checkByteFor(value));
}
Doing it the nice way requires to implement an enum class (which, in real life, is more complex than in this example, because .equals() must be rewritten so that Trinary.NULL.equals(null) becomes true) and converting:
private enum Trinary {TRUE, FALSE, NULL};
public URN (String value, Boolean toConvert, String x){
Trinary mode;
if(toConvert == null)
mode = Trinary.NULL;
else
mode = toConvert.equals(Boolean.TRUE) ? Trinary.TRUE : Trinary.FALSE;
switch (mode){
case TRUE:
if(!isValidURN(value)) throw new MalformedURLException("The string could not be parsed.");
this.value = value;
break;
case FALSE:
this.value = value.concat(checkByteFor(value));
break;
case NULL:
if(isValidURN(value))
this.value = value;
else
this.value = value.concat(checkByteFor(value));
break;
}
return;
}
To my eyes, this is the better since more readable solution, but the another half of the origin method size of code just to convert is annoying, and in real life you have to care about two different nulls with the same semantic. Is there a better way to do it?
Using a null object to convey information like this is not optimal. Remember that you cannot do any method calls on a null object, which again would mean that if you in the future ever would want to call any .getClass, .equals, .compare etc., you would have to rewrite your code.
Your best option is definitely to go with the enum option.
enum Ternary {TRUE,FALSE,UNKNOWN}
You can furthermore expand the class to have a method of getting such object,
public Ternary getByValue(Boolean o) {
if(o == null)
return UNKNOWN;
if(o)
return TRUE;
return FALSE;
}
I agree that its annoying that switch does support null or treat it as default if not mentioned.
Note: Trinary can be NULL or null which might be confusing.
Instead of using true, false and null. I would suggest using meaningful names for the modes. e.g. use VALIDATING, CONCATENATING, MIXED or whatever is more appropriate.
The simplest solution is
public URN (String value, Boolean mode){
if (mode == null) {
this.value = isValidURN(value) ? values : value.concat(checkByteFor(value));
} else if (mode) {
if(!isValidURN(value))
throw new MalformedURLException("The string could not be parsed.");
this.value = value;
} else {
this.value = value.concat(checkByteFor(value));
}
return;
}
BTW Comparing with TRUE can be confusing.
Boolean b = new Boolean(true);
if (b == Boolean.TRUE) // is false !!!

Can I condition on a variable being of type String?

Is there a way to do this in java?
If variable is a String do one operation, otherwise perform another operation.
For example, given variable a
if a is a string
close program
else
continue program
I'm looking for the code that checks to see if the variable is a String or not.
if (x instanceof String) {
// do one thing
} else {
// do something else
}
Or like this:
if ((x != null) && String.class.equals(x.getClass())) {
// do one thing
} else {
// do something else
}
if (myvariable instanceof String) {
// Yes! It's a string
}
if(x instanceof String)
{
//Close
}
else
{
//Continue
}
The canonical way is, to use instanceof. But method overloading can be used as well:
public class IsString
{
public IsString ()
{
System.out.println ("String: " + isString ("7"));
Object o = "object";
System.out.println ("Object: " + isString (o));
System.out.println ("o instanceof String ?= " + (o instanceof String));
}
public boolean isString (String p)
{
return true;
}
public boolean isString (Object o)
{
return false;
}
public static void main (String args[])
{
new IsString ();
}
}
But there is a difference: If the reference is declared as Object, the String isn't detected, while instanceof will detect it.
instanceof operator is what you use in Java when you want to test whether the given object is of a certain type.
if(x instanceof String) {
String s = (String) x;
// ...
} else {
// ...
}
The use of such type-checks is discouraged in OOP. You should rather try to solve your problem by employing subtype polymorphism (or inheritance, if you will). (If you describe your specific problem, we could assist you with it.)
An interesting factoid: Scala, another statically typed language on JVM, has a following construct that lets you match over type and cast to that type in one clause:
x match {
case s: String => ...
case _ => ...
}
From the JavaDoc,
The instanceof operator compares an object to a specified type. You
can use it to test if an object is an instance of a class, an instance
of a subclass, or an instance of a class that implements a particular
interface.
Use the instanceOf like this,
if (variable instanceof String) {
// It's a string
}

Categories