I'm porting some old code that uses the int enum pattern to Enum and EnumSet. It is very easy but I don't know how translate the following code to EnumSet: :
int mask = (kind == 'C' ? CLASS_MODIFIERS
: kind == 'F' ? FIELD_MODIFIERS
: kind == 'M' ? METHOD_MODIFIERS
: (CLASS_MODIFIERS | FIELD_MODIFIERS | METHOD_MODIFIERS));
int bad_flags = flags & ~mask; // <--- this
flags &= mask; // <--- and this
~mask is simple as typing EnumSet.complementOf but I don't see how do &.
You want to use the Set method retainAll to get the intersection of two sets:
public class Test {
public enum Kind { CLASS, FIELD, METHOD }
public void applyMask(char kind, EnumSet<Kind> flags) {
final EnumSet<Kind> mask;
switch (kind) {
case 'C': mask = EnumSet.of(Kind.CLASS); break;
case 'F': mask = EnumSet.of(Kind.FIELD); break;
case 'M': mask = EnumSet.of(Kind.METHOD); break;
default: mask = EnumSet.allOf(Kind.class); break;
}
EnumSet<Kind> badFlags = EnumSet.copyOf(flags);
badFlags.removeAll(mask); // See note below
flags.retainAll(mask);
}
}
Note: I previously had the following line in place of the simpler removeAll. Tom Hawtin pointed out that removeAll is simpler and achieves the same end. Originally, I just copied the OP's original logic as closely as possible, without trying to optimize.
badFlags.retainAll(EnumSet.complementOf(mask));
CLASS_MODIFIERS, FIELD_MODIFIERS, and METHOD_MODIFIERS might be appropriate to leave as constants, since they are being used as bit masks. The link might help to clarify the point of this code.
Related
I'm attempting to generate some Bitmaps from an input-string for the chess-variant "Anti-King Chess". Unfortunately I have to do it in Java, which I'm not super familiar with. In the few lines of code i wrote so far I already found that a few things are thought about very differently in Java than in C and it's derivatives.
Like you see in the except below, I have a constructor, that takes the board as string. I iterate over it and call the function placePiece with the corresponding bitmap-long, so that that might get updated correctly.
Now I come to my first question:
Since you can't make a "call-by-reference" in Java I decided to return the updated long. That feels pretty "hacky". What would be a better way of updating the bitmaps without writing a function for every type of piece?
Second Question:
What does Java do, when I assign the return value of a function to a variable? Is it as run-time efficient as just changing a global variable, like I do with "pieces", "whitePieces" and "blackPieces"?
/*
* Parse the starting board state and build the corresponding bitmaps
*/
public Board(String[] board) {
//Go through all lines
for(int i = 0; i < board.length; i++) {
//Go through all positions
for(int j = 0; j < board[i].length(); j++) {
switch(board[i].charAt(j)) {
//Pawns
case 'P': pawns = placePiece(pawns, i, j, true); break;
case 'p': pawns = placePiece(pawns, i, j, false); break;
//Bishop
case 'B': bishops = placePiece(bishops, i, j, true); break;
case 'b': bishops = placePiece(bishops, i, j, false); break;
//Rook
case 'R': rooks = placePiece(rooks, i, j, true); break;
case 'r': rooks = placePiece(rooks, i, j, false); break;
//Knight
case 'N': knights = placePiece(knights, i, j, true); break;
case 'n': knights = placePiece(knights, i, j, false); break;
//Queen
case 'Q': queens = placePiece(queens, i, j, true); break;
case 'q': queens = placePiece(queens, i, j, false); break;
//King
case 'K': kings = placePiece(kings, i, j, true); break;
case 'k': kings = placePiece(kings, i, j, false); break;
//Anti-King
case 'A': antikings = placePiece(antikings, i, j, true); break;
case 'a': antikings = placePiece(antikings, i, j, true); break;
}
}
}
}
/*
* Function to place a Piece at the appropriate place in the bitmaps
*/
private long placePiece(long map, int row, int column, boolean white) {
//Place a 1 in the right position of the pieces long
pieces |= 1L << (row*COLUMN_NUM + column);
//Place a 1 at the right position in either the black or white pieces
if(white == true) {
whitePieces |= 1L << (row*COLUMN_NUM + column);
}else {
blackPieces |= 1L << (row*COLUMN_NUM + column);
}
//Place a 1 at the right position in the pawn long and return the changed set
return map | 1L << (row*COLUMN_NUM + column);
}
Edit: Changed (long)1 to 1L as suggested by RaceYouAnytime.
In java all primitive types are immutable, so there is no way of updating a long.
What you did is right.
You are asking questions about performance that are much above the pay grade of the typical developer.
To have true answers to your question one should look at the bytecode generated after compilation.
For example you can ask yourself if your placePiece function would be inlined or not (which possibly has a much higher impact then updating a global varible or not).
Java programmers are not really much obsessed by performance, not when dealing with in-memory operation, since we mostly deal with IO (DB, HTTP, Files) which are order of magnitude slower then memory.
So, in general we try to optimize IO, but we care much less about in memory ops.
I think you can scrape some microseconds by checking if your methods gets inlined, if not so you may use static final methods, which are essentially faster.
Methods in java are all virtual apart from final methods which cannot be overridden.
Use primitive when you can (but often the compiler would do that for you).
That being said, concerning coding style ... you almost never use final method, an try not to use primitives, which goes against my performance tips, but fits into the java mentality of abstracting as much as you can even at the expense of performance (up to a point).
All primitive types have wrapper classes in Java that can be used to avoid the problem you're talking about
Should I just pass a one-element Array with it then?
Just use Long. (the wrapper class)
private void placePiece(Long map, int row, int column, boolean white) {
documentation can be found here: https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html
Note that instantiating a Long value is more efficient if you use the "valueOf()" method.
https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#valueOf(long)
Long pawns = Long.valueOf(14L);
...
placePiece(pawns, i, j, true); break;
Also, since you're concerned about efficiency, you may want to stick with primitive types. In that case, though, it would be more efficient to type 1L rather than (long)1 so that you aren't recasting one primitive type to another every time you instantiate.
I found a great solution for my problem here:
https://chessprogramming.wikispaces.com/Bitboard+Board-Definition
Basically, you define an array, that contains all the bitmaps, then you define constants, in the given example an Enum, which doesn't work in Java, but there are ways to define constants. Then you just have to pass the constant and can have the array, that contains all the bitmaps globally.
You then call it by invoking something like board[PAWN].
I have a variable, x.
I want to call a method m() only if x is one of two possible values.
When calling m(), I want to pass an argument to it, whose value depends on the value of x.
Is there a way to do this in Java without checking the value of x more than once, and calling/writing m() in one place only (i.e. not in multiple branches of an if statement)?
One solution I'm entertaining:
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
y = null;
break;
}
if (y != null) m(y);
But I can't help but feel this is technically checking x twice, just obscuring this fact by adding a "proxy" for the second check.
(To clarify why the constraints are what they are: when reading code, I have a hard time understanding logic that branches a lot when there is a high degree of duplication between branches - it becomes a game of "spot the difference" rather than simply being able to see what is happening. I prefer to aggressively refactor such duplication away, which is a habit that serves me well in Ruby, JS, and other languages; I'm hoping I can learn to do the same for Java and make code easier for me and others to understand at a glance.)
I'm not sure of what you want to do, but you can maybe use a Map to get the 'y' parameter from 'x'
Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
if (map.containsKey(x)) {
m(map.get(x));
}
Use "goto" or equivalent:
void do_m_if_appropriate() {
// x and y are assumed to be eg. member variables
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
return; // this is the "goto equivalent" part
}
m(y);
}
Above is pretty elegant. If necessary, it's also trivial to change it to return true or false depending on if it called m(), or just y or null.
You can also do tricks with loop constructs, though some might say this is abuse of the loop construct, and you should comment it accordingly:
do { // note: not a real loop, used to skip call to m()
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
continue; // "goto equivalent" part
}
m(y);
} while(false);
Here's a solution with Optionals (my Java syntax might be slightly incorrect). Note that to you, the code looks like so, but implementation wise, it's similar to the example you posted (i.e. checks whether y is an exceptional value).
switch (x) {
case 1:
y = Optional<String>.of("foo");
break;
case 2:
y = Optional<String>.of("bar");
break;
default:
y = Optional<String>.empty();
break;
}
y.map((m's class)::m);
result = y.orElse( <value result should take if x was invalid> );
Actually it may be better to modify m() to return an Optional and just return empty if y is not valid, but I assume you want to do this check caller-side.
Why not
switch (x) {
case 1:
y = "foo";
m(y);
break;
case 2:
y = "bar";
m(y);
break;
}
This question already has answers here:
switch expression can't be float, double or boolean
(6 answers)
Closed 5 years ago.
I used to check int values in case statements but is there any way check double values too? I can't use If else. This is an assignment. Thank you.
yes, but it won't perform very well. This will work
// don't do this, unless you want readability not performance.
switch(Double.toString(d)) {
case "1.0":
break;
case "Infinity":
break;
}
Instead you should use a series of if/else statements or use a Map<Double, DoubleConsumer> for a long list of doubles.
You can use a NavigableMap for efficient range searches.
NavigableMap<Double, DoubleConsumer> map = new TreeMap<>();
// default value is an assertion error
map.put(Double.NEGATIVE_INFINITY, d -> new AssertionError(d));
double upperBound = 12345;
map.put(upperBound, d -> new AssertionError(d));
// if >= 1.0 then println
map.put(1.0, System.out::println);
public static void select(NavigableMap<Double, DoubleConsumer> map, double d) {
Map.Entry<Double, DoubleConsumer> entry = map.floorEntry(d);
entry.getValue().accept(d);
}
Since double values provide an exact representation only in case when the value can be expressed as a sum of powers of 2 that located "close enough" to each other (within the length of mantissa), and because switch works only with exact matches, you cannot use doubles in a switch in a general case.
The basic reason for it is the same as the need to be careful when using == to compare doubles. The solution is the same as well: you should use a chain of if-then-else statements to find the desired value
if (a <= 0.2) {
...
} else if (a < 0.5) {
...
} else if (a < 0.9) {
...
} else {
...
}
or use a TreeMap<Double,Something> and perform a limit search:
TreeMap<Double,Integer> limits = new TreeMap<Double,Integer>();
limits.put(0.2, 1);
limits.put(0.5, 2);
limits.put(0.9, 3);
...
Map.Entry<Double,Integer> e = limits.ceilingEntry(a);
if (e != null) {
switch(e.getValue()) {
case 1: ... break;
case 2: ... break;
case 3: ... break;
}
}
Switch cases only take byte, short, char, and int. And a few other special cases.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Lots of Java books describe the switch statement as being faster than the if else statement. But I did not find out anywhere why switch is faster than if.
Example
I have a situation I have to choose any one item out of two. I can use either use
switch (item) {
case BREAD:
//eat Bread
break;
default:
//leave the restaurant
}
or
if (item == BREAD) {
//eat Bread
} else {
//leave the restaurant
}
considering item and BREAD is a constant int value.
In the above example which is faster in action and why?
Because there are special bytecodes that allow efficient switch statement evaluation when there are a lot of cases.
If implemented with IF-statements you would have a check, a jump to the next clause, a check, a jump to the next clause and so on. With switch the JVM loads the value to compare and iterates through the value table to find a match, which is faster in most cases.
A switch statement is not always faster than an if statement. It scales better than a long list of if-else statements as switch can perform a lookup based on all the values. However, for a short condition it won't be any faster and could be slower.
The current JVM has two kinds of switch byte codes: LookupSwitch and TableSwitch.
Each case in a switch statement has an integer offset, if these offsets are contiguous (or mostly contiguous with no large gaps) (case 0: case 1: case 2, etc.), then TableSwitch is used.
If the offsets are spread out with large gaps (case 0: case 400: case 93748:, etc.), then LookupSwitch is used.
The difference, in short, is that TableSwitch is done in constant time because each value within the range of possible values is given a specific byte-code offset. Thus, when you give the statement an offset of 3, it knows to jump ahead 3 to find the correct branch.
Lookup switch uses a binary search to find the correct code branch. This runs in O(log n) time, which is still good, but not the best.
For more information on this, see here: Difference between JVM's LookupSwitch and TableSwitch?
So as far as which one is fastest, use this approach:
If you have 3 or more cases whose values are consecutive or nearly consecutive, always use a switch.
If you have 2 cases, use an if statement.
For any other situation, switch is most likely faster, but it's not guaranteed, since the binary-search in LookupSwitch could hit a bad scenario.
Also, keep in mind that the JVM will run JIT optimizations on if statements that will try to place the hottest branch first in the code. This is called "Branch Prediction". For more information on this, see here: https://dzone.com/articles/branch-prediction-in-java
Your experiences may vary. I don't know that the JVM doesn't run a similar optimization on LookupSwitch, but I've learned to trust the JIT optimizations and not try to outsmart the compiler.
So if you plan to have loads of packets memory isn't really a large cost these days and arrays are pretty fast. You also cannot rely on a switch statement to auto generate a jump table and as such it's easier to generate the jump table scenario yourself. As you can see in below example we assume a maximum of 255
packets.
To get the below result your need abstraction.. i'm not going to explain how that works so hopefully you have an understanding of that.
I updated this to set the packet size to 255 if you need more then that you'll have to do a bounds check for (id < 0) || (id > length).
Packets[] packets = new Packets[255];
static {
packets[0] = new Login(6);
packets[2] = new Logout(8);
packets[4] = new GetMessage(1);
packets[8] = new AddFriend(0);
packets[11] = new JoinGroupChat(7); // etc... not going to finish.
}
public void handlePacket(IncomingData data)
{
int id = data.readByte() & 0xFF; //Secure value to 0-255.
if (packet[id] == null)
return; //Leave if packet is unhandled.
packets[id].execute(data);
}
Edit since I use a Jump Table in C++ a lot now i'll show an example of a function pointer jump table. This is a very generic example, but I did run it and it works correctly. Keep in mind you must set the pointer to NULL, C++ will not do this automatically like in Java.
#include <iostream>
struct Packet
{
void(*execute)() = NULL;
};
Packet incoming_packet[255];
uint8_t test_value = 0;
void A()
{
std::cout << "I'm the 1st test.\n";
}
void B()
{
std::cout << "I'm the 2nd test.\n";
}
void Empty()
{
}
void Update()
{
if (incoming_packet[test_value].execute == NULL)
return;
incoming_packet[test_value].execute();
}
void InitializePackets()
{
incoming_packet[0].execute = A;
incoming_packet[2].execute = B;
incoming_packet[6].execute = A;
incoming_packet[9].execute = Empty;
}
int main()
{
InitializePackets();
for (int i = 0; i < 512; ++i)
{
Update();
++test_value;
}
system("pause");
return 0;
}
Also another point i'd like to bring up is the famous Divide and Conquer. So my above 255 array idea could be reduced to no more then 8 if statements as a worst case scenario.
I.e. but keep in mind it get's messy and hard to manage fast and my other approach is generally better, but this is utilize in cases where arrays just won't cut it. You have to figure out your use case and when each situation works best. Just as you wouldn't want to use either of these approaches if you only have a few checks.
If (Value >= 128)
{
if (Value >= 192)
{
if (Value >= 224)
{
if (Value >= 240)
{
if (Value >= 248)
{
if (Value >= 252)
{
if (Value >= 254)
{
if (value == 255)
{
} else {
}
}
}
}
}
}
}
}
At the bytecode level, subject variable is loaded only once into processor register from a memory address in the structured .class file loaded by Runtime,and this is in a switch statement; whereas in an if-statement, a different jvm instruction is produced by your code-compiling DE, and this requires that each variable be loaded in to registers although same variable is used as in next preceeding if-statement. If you know of coding in assembly language then this would be commonplace; although java compiled coxes are not bytecode, or direct machine code, the conditional concept hereof is still consistent.
Well, I tried to avoid deeper technicality upon explaining. I hope I had made the concept clear and demystified. Thank you.
I'm sure there are better examples than mine:)
Let's say that it's snowing and the users can earn points for each snowflake, but they have to do it fast to no get stuck in the snow, so this is my ex:
class apples{
public static void main(String args[]){
int points;
points = 1;
switch (points){
case 1:
System.out.println("32");
break;
case 2:
System.out.println("Almost half");
break;
case 3:
System.out.println("You're near");
break;
case 4:
System.out.println("Congratulations., You got 100 points");
default:
System.out.println("Want to start again?");
break;
}
}
}
The switch statement has been miss-used for a long time.
The original idea was to have an entry point system; a goto-like statement which worked like this :
If my value is 1; goto 1;
Else If my value is 2; goto 2;
Else If my value is 3; goto 3;
Else If goto default;
label 1 : ...;
label 2 : ...;
label 3 : ...;
label default : ...;
And people started to like this system and decided that it would be better than having a lot of if/else statements. So they used a little trick, the break; And now people really enjoy the switch as a replacement of the if/else by breaking every case of the switch.
To have a really good example of the original switch statement, you should have something like this:
public void printDaysLeftUntilNextMonday(){
switch(dayOfWeek){
case 1 :
System.out.println("Monday");
case 2 :
System.out.println("Tuesday");
case 3 :
System.out.println("Wednesday");
case 4 :
System.out.println("Thursday");
case 5 :
System.out.println("Friday");
case 6 :
System.out.println("Saturday");
case 7 :
System.out.println("Sunday");
}
}
I had a real use case on day (rare thing if you don't abuse of break; in switch) it was in a Hangman.
public void printHangman(){
switch(triesLeft){
case 1 :
printLeftLeg();
case 2 :
printRightLeg();
case 3 :
printLeftArm();
case 4 :
printRightArm();
case 5 :
printBody();
case 6 :
printHead();
}
}
If you want to have more flexibility than a HashMap (not that there's anything wrong with the solution), you can go with a chain of responsibility :
class PointScore {
private PointScore next;
private int points;
private String msg;
public PointScore(int points, String msg) {
this.points = points;
this.msg = msg;
this.next = null;
}
public PointScore setNext(PointScore next) {
this.next = next;
return next;
}
public boolean checkScore(int points) {
if (this.points == points) {
System.out.println(this.msg);
return true;
} else if (null != next) {
return next.checkScore(points);
} else {
return false;
}
}
}
Then your main entry point :
class Apples {
public static void main(String...args) {
int points;
points = 1;
// set first condition (highest priority first)
PointScore scores = new PointScore(4, "Congratulations., You got 100 points");
// set next chain members in order or priority (highest to lowest)
scores.setNext(new PointScore(3, "You're near"))
.setNext(new PointScore(2, "Almost half"))
.setNext(new PointScore(1, "32"));
if (!scores.checkScore(points)) {
System.out.println("Want to start again?");
}
}
}
This doesn't look much, but the checkScore method can perform other checks; for example, you could setup a range of values instead of a single points integer, etc.
Use a dictionary or a hashmap to map the number of points to the string.
I find switch statements make most sense when the range of a variable is bounded. So for example the days-of-the-week example given here is fine, and the one with the enum is even better.
Bit of a no-brainer, but wikipedia has an excellent page with the history, advantages and disadvantages of the switch statement, as well as a host of examples in different languages.
Okay here we go. At work we often use enum types, simple example:
public enum Colors {
RED,
GREEN,
BLUE,
YELLOW,
VIOLET,
BROWN,
ORANGE; // more to come
}
so we can switch over these literal constants:
public String colorToMood(final Colors color) {
String mood = "everything the same to me";
switch (color) {
case RED:
mood = "excited";
break;
case YELLOW:
mood = "I like the sun";
break;
case GREEN:
mood = "forests are nice";
break;
case BLUE:
mood = "I feel free like a bird in the sky";
break;
// fill in your code here for VIOLET, BROWN, ORANGE
// otherwise they get handled by the default clause
default:
mood = "I don't know your color";
break;
}
return mood;
}
Maybe you now get a better idea what the benefits of a switch in conjunction with enums are. You can even define a constructor for your enum constants, but that gets too advanced...