convert multi if-else statements to be more functional - java

How does one make an if else statement functional
boolean condition1;
boolean condition2;
final Object a = new Object();
final Object b = new Object();
final Object c = new Object();
final Object d = new Object();
if (condition1 && condition2) {
return a;
}
else if (condition1 && !condition2) {
return b;
}
else if (!condition1 && condition2) {
return c;
}
else {
return d;
}
I would like to know how can one refactor this type of conditional statements to be more functional, with no overhead in performance preferbly.
I was thinking of Mapping predicates to the object, would this be an approach?

I've added 2 more conditions to spice it up a bit. The if/else statements can get pretty in-depth, so you can use bit-wise to clarify things and merge the conditions. To me, this clarifies the code - cause it's one level deep, no matter how many conditions.
final int BIT_CONDITION_1 = 0x01;
final int BIT_CONDITION_2 = 0x02;
final int BIT_CONDITION_3 = 0x04;
final int BIT_CONDITION_4 = 0x08;
boolean condition1 = false;
boolean condition2 = false;
boolean condition3 = false;
boolean condition4 = false;
int mergedConditions = 0;
if (condition1)
mergedConditions |= BIT_CONDITION_1;
if (condition2)
mergedConditions |= BIT_CONDITION_2;
if (condition3)
mergedConditions |= BIT_CONDITION_3;
if (condition4)
mergedConditions |= BIT_CONDITION_4;
// continue as needed
// now you can check all conditions using the set bits.
switch(mergedConditions) {
case 0: // no bits set
System.out.println("No bits set");
break;
case 1:
System.out.println("Conditions set = 1");
break;
case 2:
System.out.println("Conditions set = 2");
break;
// You can also clarify case statements by using constants
case (BIT_CONDITION_1 | BIT_CONDITION_2):
System.out.println("Conditions set = 1,2");
break;
case 4:
System.out.println("Conditions set = 3");
break;
case 5:
System.out.println("Conditions set = 1,3");
break;
case 6:
System.out.println("Conditions set = 2,3");
break;
case 7:
System.out.println("Conditions set = 1,2,3");
break;
case 8:
System.out.println("Conditions set = 4");
break;
case 9:
System.out.println("Conditions set = 1,4");
break;
case 10:
System.out.println("Conditions set = 2,4");
break;
case 11:
System.out.println("Conditions set = 1,2,4");
break;
// etc ... Continue as needed
}

For two conditions there's nothing wrong with your if/then/else statements. If you have more conditions, there's a way to "simplify" the code using a truth table.
public Object method()
{
Object objects[] = { a, b, c, d }; // Assuming objects a, b, c and d exist...
boolean condition1;
boolean condition2;
/*
* Truth Table
*
* condtion1 condition2 Object
* false false d
* false true c
* true false b
* true true a
*/
int selector = (condition1 ? 0 : 1) + (condition2 ? 0 : 2);
return objects[selector];
}
Not sure if this is what you had in mind but it's a typical way to dispatch multiple conditions. While at first glance it looks arcane, if you document the entire truth table for all conditions it can be very safe, since it forces you to consider ALL possible combinations. This can really help when you have more than two conditions.

Related

Why isn't .equals recognizing my variable as the same string that I'm passing it?

So this little function is supposed to check if parentheses and brackets are matched next to each other. I feel like it should work and I've tried it a few different ways but I can't figure out how to check if my next char is what I expect it to be.
class Parenths {
public boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i+=2) {
String curr= String.valueOf(parens[i]);
String next = String.valueOf(parens[i+1]);
// System.out.println(next.equals(")"); --------> false
// System.out.println(Object.equals(next, ")")); ----> error
switch (curr) {
case "(": if (!next.equals(")")) return false;
case "{": if (!next.equals("}")) return false;
case "[": if (!next.equals("]")) return false;
}
}
return true;
}
}
You can see the lines I printed to debug and it seems that .equals is not the right thing to use here? Can anyone explain why this isn't working?
PS. I realize I don't have to convert the string to a char array to compare elements, so unless that's the only fix, please don't point that out to me.
Not tested, but it seems to be a problem of fall through. Try to replace if (boolean) return boolean with return boolean, this should do the trick.
The problem is that you don't have a break at the end of the cases, so if, for example, your first case is true, it will not stop execution and execute the 2nd test, which will be false. If you change your conditional statements to a direct return, you will not have this problem.
EDIT: Sorry, I read too quickly. Doing so will break your loop. Actually, you have to add a break at the end of the cases.
case "(": if (!next.equals(")")) return false; break;
case "{": if (!next.equals("}")) return false; break;
case "[": if (!next.equals("]")) return false; break;
First , you have to add break; after the cases its important to stop seeing the cases
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
}
Secondly , your code doesnt support the confrotation of a closing patenthesis at first , you have to add a default case
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
Also , you have to make sure the next element is not null before comparing to it , and dont increment with 2 , you give a String with a one element and that's why you get the error
public static boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i++) {
String curr= String.valueOf(parens[i]);
String next = "";
try {
next = String.valueOf(parens[i+1]);
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
}catch(Exception e) {}
}
return false;
}
Test :
System.out.println(isValid("()"));
// Output : true
System.out.println(isValid("("));
// Output : false

Java, class, Boolean, logic mess

So, we were given to code this ScantronGrader for homework, and the specs say that we have to create this class isValid to check to validity of the options that fall into either A, B, C, or D (all uppercase), I first tried switch (error), if-else-if (error); do-while (Oh, I know so wrong and error). I tried for loop first, and the value didn't get incremented.
In its recent rendition, this is my issue. TBH, I don't even know what I am doing anymore.
public static boolean isValid(String inputstr)
{
int x = 0;
do
{
switch (inputstr.charAt(x))
{
case 'A':
case 'B':
case 'C':
case 'D':
return true;
default: return false;
x++;
}
} while (x < inputstr.length());
}
}
The problem with this is that it is not letting me increment the counter. Now, I need to do that, else, how would I shift right? Either way, please HALP.
Not sure if i understood what that method have to do, but if it has to return true only if the string have those letter you can do this:
public static boolean isValid(String inputstr)
{
int x = 0;
boolean bool = true;
do
{
if(!(inputstr.charAt(x) == 'A' || inputstr.charAt(x) == 'B' || inputstr.charAt(x) == 'C' || inputstr.charAt(x) == 'D'))
{
bool = false;
}
x++;
}while (x < inputstr.length());
return bool;
}
Okay, so after some ideas from here (Thank you for reaching out to help), I am toying with this one which seems to work. Just let me know if I am doing anything unnecessary/ useless, or there is a more efficient way to do this, please?
public static boolean isValid(String inputstr) {
int count = 0;
for (int x = 0; x < inputstr.length(); x++) {
switch (inputstr.charAt(x)) {
case 'A':
case 'B':
case 'C':
case 'D':
break;
default: count++;
}
}
if (count == 0) {
return true;
}
else {
return false;
}
}

Checking if a field is set to its declared, default value in Java

Let's say that I have a class with a static field with a set default value:
public class MyClass {
public static int numb = 10;
}
Now, during program runtime, how would I check if MyClass's numb field is set to its default value (in this case, 10)?
From my standpoint, in code, I don't know what the field is set to by default, and I am not the one setting the field, so I can't "simply check if numb == 10." I have to be able to check if it is set to exactly what it was declared as in the source code.
It's not possible with a single field. I would suggest adding a constant to hold the default, and comparing it against numb to see if it's changed:
private static final int DEFAULT = 10;
public static int numb = DEFAULT;
public static boolean isChanged() {
return numb != DEFAULT;
}
Kröw, with your latest clarification of the problem, does the below meet your requirement?
public class MyClass {
public static int numb = 10;
}
public class MyTest {
private static int default_numb = MyClass.numb;
public static boolean isChanged() {
return MyClass.numb != default_numb;
}
public static void main(String[] args) {
System.out.println(isChanged() + " " + MyClass.numb);
MyClass.numb = 20;
System.out.println(isChanged() + " " + MyClass.numb);
MyClass.numb = 10;
System.out.println(isChanged() + " " + MyClass.numb);
}
}
The output of running MyTest is:
$ java MyTest
false 10
true 20
false 10
The problem description says "From my standpoint, in code, I don't know what the field is set to by default,"
If the numb default value is being provided at runtime, then the following code will accomplish what you are looking for.
public class MyClass {
private static int numb;
private static int def_numb;
private static boolean initialized = false; // track numb initialize
public MyClass(int default_value) {
if (!initialized) {
numb = default_value;
def_numb = numb;
initialized = true;
} else {
numb = default_value;
}
}
public void setNumb(int value) {
numb = value;
}
public int getNumb() {
return numb;
}
public boolean isChanged() {
return numb != def_numb;
}
public static void main(String[] args) {
MyClass m2 = new MyClass(5);
System.out.println(m2.isChanged() + " " + m2.getNumb());
MyClass m3 = new MyClass(6);
System.out.println(m2.isChanged() + " " + m2.getNumb());
System.out.println(m3.isChanged() + " " + m3.getNumb());
MyClass m4 = new MyClass(5);
System.out.println(m3.isChanged() + " " + m3.getNumb());
}
}
The following will be displayed by running this program.
$ java MyClass
false 5
true 6
true 6
false 5
If you do not have any idea of the default value, you should track the variable for any changes. Since it is a public and static variable i do not think it is possible. However, you can change your solution as suggested in the below.
Use MyValueChangeListener or Java debugger API
Check this
When I made this question, I was hoping to get an answer from someone who new about a few methods that reflectively found the value that a variable was initialized to. This kinda seemed like something that reflection would support. But after I posted the question, I realized that there'd be no substantial reason for Java to permanently store the initial value of something in memory.
Solution
Anyways, I forged a method that reflectively accesses the current value of a variable during runtime, then reads the program's bytecode to check what the variable was when the class was initialized. To do this, it emulates the class's initialization (<clinit>) and then simply checks for equality of the variable's current and declared values. (It has a lot of setbacks; see below.)
/**
* Checks if the current value of a variable is the same as the value it was
* declared as during class initialization. Rules dictating whether or not this
* method can check for the default value of a given variable are as follows:
* <ol>
* <li>The variable must be static.</li>
* <li>The variable must have been initialized to the value of a constant
* expression.</li>
* <li>The variable must be a primitive type.</li>
* </ol>
*
* #param varName
* The name of the variable to be checked. This variable must be
* static and belong to the {#link Class}, <code>clas</code>.
* #param clas
* The class of which a static variable, named <code>varName</code>,
* belongs.
* #return <code>true</code> if the specified variable's value as set in the
* bytecode is the same as it is when retrieved reflectively at the
* beginning of this method call, <code>false</code> otherwise.
* #throws UnsupportedOperationException
* If the specified variable's type is not primitive.
* #throws SecurityException
* As thrown by {#link Class#getDeclaredField(String)} and any other
* reflective operation executed by this method.
* #throws NoSuchFieldException
* If attempting to access the field with the given arguments to
* this method, throws a {#link NoSuchFieldException}.
* #throws IllegalArgumentException
* In case the <code>varName</code> parameter does refer to a field
* of the given class, but the field is not static.
* #throws RuntimeException
* In case an unknown or unexpected error occurs.
* #throws IOException
* If an IOException occurs while reading from the
* <code>.class</code> file of the specified class.
*/
public static boolean isOriginalValue(String varName, Class<?> clas) throws UnsupportedOperationException,
NoSuchFieldException, SecurityException, IllegalArgumentException, RuntimeException, IOException {
Object currentValue;
// Check for the current value reflectively:
Field field = clas.getDeclaredField(varName);
if (!field.getType().isPrimitive())
throw new UnsupportedOperationException("The specified variable's type is not primitive.");
field.setAccessible(true);
try {
// We pass in null because we assume that the field is static. If it isn't, an
// IllegalArgumentException is thrown.
currentValue = field.get(null);
} catch (IllegalAccessException e) {
throw new RuntimeException("The current value of the variable could not be accessed.", e);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Map used to store constant pool values:
Map<Integer, Object> constants = new HashMap<>();
// Local classes used to represent certain constant pool items:
class CPoolClass {
public CPoolClass(int internalNameIndex) {
}
}
class CPoolNameAndType {
public final int nameIndex;
public CPoolNameAndType(int nameIndex, int typeIndex) {
this.nameIndex = nameIndex;
}
public String getName() {
return (String) constants.get(nameIndex);
}
}
class CPoolField {
public final int nameAndTypeIndex;
public CPoolField(int classIndex, int nameAndTypeIndex) {
this.nameAndTypeIndex = nameAndTypeIndex;
}
public CPoolNameAndType getNameAndType() {
return (CPoolNameAndType) constants.get(nameAndTypeIndex);
}
}
class CPoolString {
public CPoolString(int stringIndex) {
}
}
// Now to read the bytecode of the class for the original value.
// First, we open a stream to the .class file of clas.
DataInputStream reader = new DataInputStream(clas.getResourceAsStream(clas.getSimpleName() + ".class"));
// A .class file starts with the magic hexadecimal code: 0xCafeBabe.
if (reader.readInt() != 0xCafeBabe)
throw new RuntimeException("Failed to parse the given class's .class file header.");
// Next, the file contains four bytes denoting its version.
reader.readInt();// Read and ditch the four bytes; we don't need them.
// Parse the constant pool size (2 bytes). We'll go through this many items in
// the constant pool, and cache the ones we need.
int constantPoolSize = reader.readShort();
// Constant pool is of size constantPoolSize-1, so we iterate from 1 to the
// size.
for (int i = 1; i < constantPoolSize; i++) {
byte tag = reader.readByte();
switch (tag) {
default:
throw new RuntimeException(
"Could not parse the .class file's constant pool; couldn't determine the initial value of the variable.");
case 1:// String tag
constants.put(i, reader.readUTF());
continue;
case 3:// Int tag
constants.put(i, reader.readInt());
continue;
case 4:// Float tag
constants.put(i, reader.readFloat());
continue;
case 5:// Long tag
constants.put(i, reader.readLong());
i++;
continue;
case 6:// Double tag
constants.put(i, reader.readDouble());
i++;
continue;
case 7:// Class item
constants.put(i, new CPoolClass(reader.readShort()));
continue;
case 8:// Literal String (e.g. "abc", "potato", "a string")
constants.put(i, new CPoolString(reader.readShort()));
continue;
case 9:// Field item
constants.put(i, new CPoolField(reader.readShort(), reader.readShort()));
continue;
case 10:// Method (We don't need to cache this)
case 11:// Abstract method
reader.readInt();
continue;
case 12:// NameAndType item
constants.put(i, new CPoolNameAndType(reader.readShort(), reader.readShort()));
continue;
case 15:// Method Handle
reader.readByte();
reader.readShort();
continue;
case 16:// Method Type
reader.readShort();// Skip 2 bytes
continue;
case 18:// Invoke Dynamic
reader.readInt();
continue;
}
}
// After the constant pool, there are a few, 2 byte-sized values, a list of
// interfaces (that the class implements), a list of fields, then the list of
// methods.
//
// We're gonna skip to the methods.
reader.readInt();// Skip 4 bytes
reader.readShort();// Skip 2 bytes
int interfaceListSize = reader.readShort();
for (int i = 0; i < interfaceListSize; i++)
reader.readShort();
int fieldListSize = reader.readShort();
for (int i = 0; i < fieldListSize; i++) {
// Skip 6 bytes (total)
reader.readShort();
reader.readInt();
int attributeCount = reader.readShort();
// Skip through all the attributes.
for (int j = 0; j < attributeCount; j++) {
reader.readShort();
int attributeSize = reader.readInt();
for (int k = 0; k < attributeSize; k++)
reader.readByte();
}
}
int methodCount = reader.readShort();
for (int i = 0; i < methodCount; i++) {
// Skip the method's modifiers.
reader.readShort();
// Static variables are initialized via the <clinit> method, whether or not they
// are placed in static initialization blocks in the source code. Because of
// this, we'll have to check the code in this method.
boolean isClinit = "<clinit>".equals(constants.get((int) reader.readShort()));
reader.readShort();// Skip over the method descriptor.
short attributeCount = reader.readShort();
if (isClinit) {
// This is the method we want. Iterate over each attribute it has.
for (int j = 0; j < attributeCount; j++) {
if ("Code".equals(constants.get((int) reader.readShort()))) {
reader.readInt();// Skip over the attribute size. We only need the code table size.
reader.readInt();// Skip max stack size and max locals.
int codeLength = reader.readInt();
// Doubles and longs in the stack will have a null value after them. This
// emulates the numbering of an actual stack.
Stack<Object> stack = new Stack<Object>() {
private static final long serialVersionUID = 1L;
// Handles the push method
#Override
public void addElement(Object item) {
super.addElement(item);
if (item instanceof Double || item instanceof Long)
super.addElement(null);
}
// Handles the add method
#Override
public synchronized void insertElementAt(Object obj, int index) {
if (obj instanceof Double || obj instanceof Long)
super.insertElementAt(null, index);
super.insertElementAt(obj, index);
}
#Override
public synchronized Object pop() {
Object item = super.pop();
if (item == null)
return super.pop();
return item;
}
#Override
public synchronized Object remove(int index) {
Object item = super.remove(index);
if (item == null)
item = super.remove(index - 1);
else if (item instanceof Double || item instanceof Long)
super.remove(index);
return item;
}
#Override
public synchronized Object peek() {
Object item = super.peek();
if (item == null)
return super.get(size() - 2);
return item;
}
};
int[] bytes = new int[codeLength];
for (int k = 0; k < codeLength; k++)
bytes[k] = reader.readUnsignedByte();
// Stack<Object> locals = new Stack<>();
// If I supported local vars, I'd feel obligated to support arrays here, as
// well, and, right now, I don't have enough time for that. Feel free to edit
// this question. Otherwise, I may edit this method to support more opcodes
// later.
Object variable = null;
// Here is where we simulate the class's initialization. This process doesn't
// handle things like arrays, method calls, or other variables.
for (int k = 0; k < codeLength; k++) {
// When parsing through mnemonics, we ignore anything that only puts a reference
// onto the stack or removes a reference from the stack, since this method only
// supports primitive types.
switch (bytes[k]) {
default:
continue;
// Pushing
case 0x10:// bipush
stack.push(bytes[++k]);
break;
case 0x11:// sipush
stack.push((bytes[++k] << 8) + bytes[++k]);
break;
case 0x12:// ldc
case 0x14:// ldc2_w
Object item = constants.get((bytes[++k] << 8) + bytes[++k]);
if (item instanceof Integer || item instanceof Float || item instanceof Long
|| item instanceof Double)
stack.push(item);
break;
// Doubles
case 0xe:// dconst_0
stack.push((double) 0);
break;
case 0xf:// dconst_1
stack.push((double) 1);
break;
case 0x63:// dadd
stack.push((double) stack.pop() + (double) stack.pop());
break;
case 0x6f:// ddiv
stack.push((double) stack.pop() / (double) stack.pop());
break;
case 0x6b:// dmul
stack.push((double) stack.pop() * (double) stack.pop());
break;
case 0x77:// dneg
stack.push(-(double) stack.pop());
break;
case 0x73:// drem
stack.push((double) stack.pop() % (double) stack.pop());
break;
case 0x67:// dsub
stack.push((double) stack.pop() - (double) stack.pop());
break;
case 0x59:// dup
stack.push(stack.peek());
break;
case 0x5a:// dup_x1
case 0x5d:// dup2_x1
stack.add(stack.size() - 2, stack.peek());
break;
case 0x5b:// dup_x2
case 0x5e:// dup2_x2
stack.add(stack.size() - 3, stack.peek());
break;
// Floats
case 0xb:// fconst_0
stack.push(0f);
break;
case 0xc:// fconst_1
stack.push(1f);
break;
case 0xd:// fconst_2
stack.push(2f);
break;
case 0x62:// fadd
stack.push((float) stack.pop() + (float) stack.pop());
break;
case 0x6e:// fdiv
stack.push((float) stack.pop() / (float) stack.pop());
break;
case 0x6a:// fmul
stack.push((float) stack.pop() * (float) stack.pop());
break;
case 0x76:// fneg
stack.push(-(float) stack.pop());
break;
case 0x72:// frem
stack.push((float) stack.pop() % (float) stack.pop());
break;
case 0x66:// fsub
stack.push((float) stack.pop() - (float) stack.pop());
break;
// Integers
case 0x2:// iconst_m1
stack.push(-1);
break;
case 0x3:// iconst_0
stack.push(0);
break;
case 0x4:// iconst1
stack.push(1);
break;
case 0x5:// iconst_2
stack.push(2);
break;
case 0x6:// iconst_3
stack.push(3);
break;
case 0x7:// iconst_4
stack.push(4);
break;
case 0x8:// iconst_5
stack.push(5);
break;
case 0x60:// iadd
stack.push((int) stack.pop() + (int) stack.pop());
break;
case 0x7e:// iand
stack.push((int) stack.pop() & (int) stack.pop());
break;
case 0x6c:// idiv
stack.push((int) stack.pop() / (int) stack.pop());
break;
case 0x68:// imul
stack.push((int) stack.pop() * (int) stack.pop());
break;
case 0x74:// ineg
stack.push(-(int) stack.pop());
break;
case 0x80:// ior
stack.push((int) stack.pop() | (int) stack.pop());
break;
case 0x70:// irem
stack.push((int) stack.pop() % (int) stack.pop());
break;
case 0x78:// ishl
stack.push((int) stack.pop() << (int) stack.pop());
break;
case 0x7a:// ishr
stack.push((int) stack.pop() >> (int) stack.pop());
break;
case 0x64:// isub
stack.push((int) stack.pop() - (int) stack.pop());
break;
case 0x7c:// iushr
stack.push((int) stack.pop() >>> (int) stack.pop());
break;
case 0x82:// ixor
stack.push((int) stack.pop() ^ (int) stack.pop());
break;
// Longs
case 0x9:// lconst_0
stack.push(0l);
break;
case 0xa:// lconst_1
stack.push(1l);
break;
case 0x61:// ladd
stack.push((long) stack.pop() + (long) stack.pop());
break;
case 0x7f:// land
stack.push((long) stack.pop() & (long) stack.pop());
break;
case 0x6d:// ldiv
stack.push((long) stack.pop() / (long) stack.pop());
break;
case 0x69:// lmul
stack.push((long) stack.pop() * (long) stack.pop());
break;
case 0x75:// lneg
stack.push(-(long) stack.pop());
break;
case 0x81:// lor
stack.push((long) stack.pop() | (long) stack.pop());
break;
case 0x71:// lrem
stack.push((long) stack.pop() % (long) stack.pop());
break;
case 0x79:// lshl
stack.push((long) stack.pop() << (long) stack.pop());
break;
case 0x7b:// lshr
stack.push((long) stack.pop() >> (long) stack.pop());
break;
case 0x65:// lsub
stack.push((long) stack.pop() - (long) stack.pop());
break;
case 0x7d:// lushr
stack.push((long) stack.pop() >>> (long) stack.pop());
break;
case 0x83:// lxor
stack.push((long) stack.pop() ^ (long) stack.pop());
break;
// Stack manipulation
// nop is handled by this switch's default case.
case 0x58:// pop2
stack.pop();
case 0x57:// pop
stack.pop();
break;
case 0x5f:// swap
Object top = stack.pop(), bottom = stack.pop();
stack.push(top);
stack.push(bottom);
break;
// Variable assignment
case 0xb3:// putstatic
if (varName.equals(((CPoolField) constants.get((bytes[++k] << 8) + bytes[++k]))
.getNameAndType().getName()))
variable = stack.pop();
break;
// Casting
case 0x90:// d2f
stack.push((float) (double) stack.pop());
break;
case 0x8e:// d2i
stack.push((int) (double) stack.pop());
break;
case 0x8f:// dtl
stack.push((long) (double) stack.pop());
break;
case 0x91:// i2b
stack.push((byte) (int) stack.pop());
break;
case 0x92:// i2c
stack.push((char) (int) stack.pop());
break;
case 0x87:// i2d
stack.push((double) (int) stack.pop());
break;
case 0x86:// i2f
stack.push((float) (int) stack.pop());
break;
case 0x85:// i2l
stack.push((long) (int) stack.pop());
break;
case 0x93:// i2s
stack.push((short) (int) stack.pop());
break;
case 0x8a:// l2d
stack.push((double) (long) stack.pop());
break;
case 0x89:// l2f
stack.push((float) (long) stack.pop());
break;
case 0x88:// l2i
stack.push((int) (long) stack.pop());
break;
case 0x8d:// f2d
stack.push((double) (float) stack.pop());
break;
case 0x8b:// f2i
stack.push((int) (float) stack.pop());
break;
case 0x8c:// ftl
stack.push((long) (float) stack.pop());
break;
// Comparisons
case 0x98:// dcmpg
stack.push((double) stack.pop() > (double) stack.pop());
break;
case 0x96:// fcmpg
stack.push((float) stack.pop() > (float) stack.pop());
break;
case 0x97:// dcmpl
stack.push((double) stack.pop() < (double) stack.pop());
break;
case 0x95:// fcmpl
stack.push((float) stack.pop() < (float) stack.pop());
break;
case 0x94:// lcmp
stack.push(((Long) stack.pop()).compareTo((Long) stack.pop()));
break;
}
}
return variable.equals(currentValue);
} else
// This isn't the "Code" attribute. Skip it.
for (int k = 0; k < reader.readInt(); k++)
reader.readByte();
}
// If we iterated through each
throw new RuntimeException(
"Couldn't find the static initialization bytecode for the specified class. Any initial assignments or declarations to the specified variable could not be found.");
} else {
// We don't want this method.
for (int j = 0; j < attributeCount; j++) {
reader.readShort();// Skip the attribute name. We don't care for this method.
for (int k = 0; k < reader.readInt(); k++)
reader.readByte();// Skip the attribute data.
}
}
}
throw new RuntimeException("The declared value could not be found");
}
This method generally works for variables with simple declared values (e.g. public static int x = 56;). There is a large quantity of opcodes that it doesn't support, including some that take arguments (so if those opcodes exist in the bytecode of the class, this method won't read them correctly). This method does "work" in extremely simple cases and is more for a proof of concept.

Switch Statement: Execute Code Once

If I have a switch statement testing the value of integer i, how can I execute the same code once?
For example:
switch(i) {
case 0:
if(j == 2) {
booleanA = true;
booleanB = false;
case 1:
if(j == 4) {
booleanA = true;
booleanB = false;
}
With 5 different cases, instead of me having to type out
booleanA = true;
booleanB = false;
five times, is there a way to say if one of the if statements is true, use this block of code? Is that possible?
Thanks!
You can do it without a switch statement...
int[] requiredJ = {2,4};
if (j == requiredJ[i]) {
booleanA = true;
booleanB = false;
}
I can not understand logic behind your code, but may be this can be done ( Like switch hit in cricket !!! :p).
Assign the values to your booleans, and revert in default case.
booleanA = true;
booleanB = false;
// more code blocks
switch(i) {
case 0:
// Process
break;
case 1:
// Process
break;
default :
booleanA = false;
booleanB = true;
}

java switch case question

public String sizeOfSupermarket() {
String size;
switch (this.numberOfProducts) {
case (this.numberOfProducts > 5000):
size = "Large";
break;
case (this.numberOfProducts > 2000 && this.numberOfProducts < 5000):
size = "Medium";
break;
case (this.numberOfProducts < 2000):
size = "Small";
break;
}
return size;
}
the above is wrong, how to write the compare statement in case statement?
You can use a derived value, in this case look at the number of thousands.
public String sizeOfSupermarket() {
switch (this.numberOfProducts/1000) {
case 0: case 1: return "Small";
case 2: case 3: case 4: return "Medium";
default: return "Large";
}
}
Note: you have a bug in your code such that if the numberOfProducts is exactly 2000 or 5000, it will return null (assuming it compiled)
You can't use expressions in case statements. The condition is evaluated by the switch statement, and the case statements check if the result matches.
To do what you are trying to do, you will have to use a series of if and else if statements:
if(this.numberOfProducts > 5000) {
size = "Large";
}
else if(this.numberOfProducts > 2000 && this.numberOfProducts < 5000) {
size = "Medium";
}
else {
size = "Small";
}
if (numberOfProducts >= 5000)
size = "Large";
else if (numberOfProducts >= 2000)
size = "Medium";
else
size = "Small";
You cannot use switch to test for boolean expressions. You need to use if.
You can use switch if you want to check if a variable has one certain value, i.e.:
public String sizeOfSupermarket() {
String size;
switch (this.numberOfProducts) {
case 5000:
size = "Large";
break;
case 2000:
size = "Medium";
break;
case 100):
size = "Small";
break;
}
return size;
}
Java 1.6 does not support a conditional switch statement, your best bet would be to use the if then else control structure
No way. By definition switch/case is based on enumerated types only (int, boolean, long, enum) in all C-like languages I know.
So you have to use if/else structure here:
public String sizeOfSupermarket() {
String size;
if (this.numberOfProducts > 5000) {
size = "Large";
} else if (this.numberOfProducts > 2000 && this.numberOfProducts < 5000) {
size = "Medium";
} else (this.numberOfProducts < 2000) {
size = "Small";
}
return size;
}

Categories

Resources