We know it can in JavaScript.
But is it possible to print "Success" message on the condition given below in Java?
if (a==1 && a==2 && a==3) {
System.out.println("Success");
}
Someone suggested:
int _a = 1;
int a = 2;
int a_ = 3;
if (_a == 1 && a == 2 && a_ == 3) {
System.out.println("Success");
}
But by doing this we are changing the actual variable. Is there any other way?
Yes, it's quite easy to achieve this with multiple threads, if you declare variable a as volatile.
One thread constantly changes variable a from 1 to 3, and another thread constantly tests that a == 1 && a == 2 && a == 3. It happens often enough to have a continuous stream of "Success" printed on the console.
(Note if you add an else {System.out.println("Failure");} clause, you'll see that the test fails far more often than it succeeds.)
In practice, it also works without declaring a as volatile, but only 21 times on my MacBook. Without volatile, the compiler or HotSpot is allowed to cache a or replace the if statement with if (false). Most likely, HotSpot kicks in after a while and compiles it to assembly instructions that do cache the value of a. With volatile, it keeps printing "Success" forever.
public class VolatileRace {
private volatile int a;
public void start() {
new Thread(this::test).start();
new Thread(this::change).start();
}
public void test() {
while (true) {
if (a == 1 && a == 2 && a == 3) {
System.out.println("Success");
}
}
}
public void change() {
while (true) {
for (int i = 1; i < 4; i++) {
a = i;
}
}
}
public static void main(String[] args) {
new VolatileRace().start();
}
}
Using concepts (and code) from a brilliant code golf answer, Integer values can be messed with.
In this case, it can make ints casted to Integers be equal when they wouldn't normally be:
import java.lang.reflect.Field;
public class Test
{
public static void main(String[] args) throws Exception
{
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
// array[129] is 1
array[130] = array[129]; // Set 2 to be 1
array[131] = array[129]; // Set 3 to be 1
Integer a = 1;
if(a == (Integer)1 && a == (Integer)2 && a == (Integer)3)
System.out.println("Success");
}
}
Unfortunately it's not quite as elegant as Erwin Bolwidt's multithreaded answer (as this one requires Integer casting), but still some fun shenanigans take place.
In this question #aioobe suggests (and advise against) the use of C preprocessor for Java classes.
Although it is extremely cheaty, that's my solution:
#define a evil++
public class Main {
public static void main(String[] args) {
int evil = 1;
if (a==1 && a==2 && a==3)
System.out.println("Success");
}
}
If executed using the following commands it will output exactly one Success:
cpp -P src/Main.java Main.java && javac Main.java && java Main
As we already know that it is possible to make this code evaluate to true thanks to great answers of Erwin Bolwidt and phflack, I wanted to show that you need to keep a high level of attention when dealing with a condition that looks like the one presented in the question, as sometimes what you see might not be exactly what you think it is.
This is my attempt to show that this code prints Success! to the console. I know I cheated a bit, but I still think this is a good place to present it right here.
No matter what the purposes of writing code like this are - better to know how to deal with the following situation and how to check if you're not wrong with what you think you see.
I used the Cyrillic 'a' which is a distinct character from the latin 'a'. You can inspect the characters used in the if statement here.
This works because the names of the variables are taken from different alphabets. They are distinct identifiers, creating two distinct variables with a different value in each.
Note that if you want this code to work properly, character encoding needs to be changed to one supporting both characters, e.g. all Unicode encodings (UTF-8, UTF-16 (in BE or LE), UTF-32, even UTF-7), or Windows-1251, ISO 8859-5, KOI8-R (thank you - Thomas Weller and Paŭlo Ebermann - for pointing it out):
public class A {
public static void main(String[] args) {
int а = 0;
int a = 1;
if(а == 0 && a == 1) {
System.out.println("Success!");
}
}
}
(I hope you will never have to deal with that sort of problem any time in the future.)
There is another way to approach this (in additional to the volatile data-racing approach that I posted earlier), using the power of PowerMock. PowerMock allows methods to be replaced with other implementations. When that is combined with auto-unboxing, the original expression (a == 1 && a == 2 && a == 3), without modification, can be made true.
#phflack's answer relies on modifying the auto-boxing process in Java that uses the Integer.valueOf(...) call. The below approach relies on modifying auto-unboxing by changed the Integer.intValue() call.
The advantage of the below approach is that the original if-statement given by the OP in the question is used unchanged, which I think is the most elegant.
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.support.membermodification.MemberModifier.replace;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#PrepareForTest(Integer.class)
#RunWith(PowerMockRunner.class)
public class Ais123 {
#Before
public void before() {
// "value" is just a place to store an incrementing integer
AtomicInteger value = new AtomicInteger(1);
replace(method(Integer.class, "intValue"))
.with((proxy, method, args) -> value.getAndIncrement());
}
#Test
public void test() {
Integer a = 1;
if (a == 1 && a == 2 && a == 3) {
System.out.println("Success");
} else {
Assert.fail("(a == 1 && a == 2 && a == 3) != true, a = " + a.intValue());
}
}
}
Since this seems to be a follow-up of this JavaScript question, it’s worth noting that this trick and similar works in Java too:
public class Q48383521 {
public static void main(String[] args) {
int aᅠ = 1;
int ᅠ2 = 3;
int a = 3;
if(aᅠ==1 && a==ᅠ2 && a==3) {
System.out.println("success");
}
}
}
On Ideone
But note that this isn’t the worst thing you could do with Unicode. Using white-space or control characters that are valid identifiers parts or using different letters that look the same still creates identifiers that are different and can be spotted, e.g. when doing a text search.
But this program
public class Q48383521 {
public static void main(String[] args) {
int ä = 1;
int ä = 2;
if(ä == 1 && ä == 2) {
System.out.println("success");
}
}
}
uses two identifiers that are the same, at least from the Unicode point of view. They just use different ways to encode the same character ä, using U+00E4 and U+0061 U+0308.
On Ideone
So depending on the tool you’re using, they may not only look the same, Unicode enabled text tools may not even report any difference, always finding both when searching. You may even have the problem that the different representations get lost when copying the source code to someone else, perhaps trying to get help for the “weird behavior”, making it non-reproducible for the helper.
Inspired by the #Erwin's excellent answer, I wrote a similar example, but using Java Stream API.
And an interesting thing is that my solution works, but in very rare cases (because just-in-time compiler optimizes such a code).
The trick is to disable any JIT optimizations using the following VM option:
-Djava.compiler=NONE
In this situation, the number of success cases increases significantly. Here is the code:
class Race {
private static int a;
public static void main(String[] args) {
IntStream.range(0, 100_000).parallel().forEach(i -> {
a = 1;
a = 2;
a = 3;
testValue();
});
}
private static void testValue() {
if (a == 1 && a == 2 && a == 3) {
System.out.println("Success");
}
}
}
P.S. Parallel streams use ForkJoinPool under the hood, and variable a is shared between multiple threads without any synchronization, that's why the result is non-deterministic.
Along similar lines, by forcing a float (or double) to underflow (or overflow) through division (or multiplication) by a large number:
int a = 1;
if (a / Float.POSITIVE_INFINITY == 1 / Float.POSITIVE_INFINITY
&& a / Float.POSITIVE_INFINITY == 2 / Float.POSITIVE_INFINITY
&& a / Float.POSITIVE_INFINITY == 3 / Float.POSITIVE_INFINITY) {
System.out.println("Success");
}
Related
I am working on a project in my Java class that is using multiple classes as well as GUI (not sure if that info is relevant). My group partner and I have come across an issue though. We have a Validator class, that should validate a "SSN" but we are continuously given the error:
java:146: error: incompatible types: double cannot be converted to boolean
if(Validator.isValidSSN(jTextFieldEmpSSN)){
Now obviously java:146 is the line. the code we have for each class is:
employeeUI class (the one showing the error):
private void jButtonEnterActionPerformed(java.awt.event.ActionEvent evt)
{
Employee e=new Employee();
if(Validator.isValidName(jTextFieldEmpFirst)){
if(Validator.isValidName(jTextFieldEmpLast)){
if(Validator.isValidEmail(jTextFieldEmpEmail)){
if(Validator.isValidSSN(jTextFieldEmpSSN)){
e.setFirstName(jTextFieldEmpFirst.getText());
e.setLastName(jTextFieldEmpLast.getText());
e.setEmailAdd(jTextFieldEmpEmail.getText());
e.setSSN(Integer.parseInt(jTextFieldEmpSSN.getText()));
}}}}
and the Validator class for isValidSSN is:
public static double isValidSSN(JTextField textfield)
{
double number = 0;
boolean inRange = false;
while(!inRange)
{
number = Double.parseDouble(textfield.getText());
if (number >= 100000000 && number <= 999999999)
{
inRange = true;
} else {}
}
return number;
}
We have been beating our head on how to fix this for quite some time, but are coming up at a loss. Are we missing something? we would greatly appreciate any help with this.
If I ask, "Is 123-45-6789" a valid SSN?" you wouldn't reply "123456789.0", would you? You'd give me a yes or a no. By returning double your method is doing the former. It's responding with a number instead of an answer to the question.
A good rule of thumb is that methods starting with is or has should return booleans. "Is this a valid SSN?" is a yes/no question, so isValidSSN should return the programming equivalent of yes/no.
public static boolean isValidSSN(JTextField textfield)
There are a couple of other design points here:
The loop isn't necessary. The SSN is either valid or it isn't.
A text field is not itself an SSN. It holds some text, and that text is the SSN. Rather than taking a text field and looking up the text in the field with getText(), it'd be better to have isValidSSN take the text directly. Let the caller extract the text from the text field.
In broader terms this is known as the single responsibility principle. Every method should ideally do just one thing.
Result:
public static boolean isValidSSN(String ssn) {
double number = Double.parseDouble(ssn);
if (number >= 100000000 && number <= 999999999) {
return true;
}
else {
return false;
}
}
P.S. If I don't mention it someone will surely comment that the if and else blocks aren't necessary; one can return the if result directly. They would be right, though I consider it a bit of an advanced trick. It would look like so:
public static boolean isValidSSN(String ssn) {
double number = Double.parseDouble(ssn);
return number >= 100000000 && number <= 999999999;
}
Say I have a list of many primitive variables:
final int a = 3;
final int b = 4;
final int c = 4;
final int d = 4;
final int e = 4;
What's an idiomatic way to make sure they all hold the same value? The obvious way is simply
if (a == b && a == c && a == d && a == e) // ...
But I think this is error prone and hard to read, especially when the variables have proper names, unlike my example.
if ( numCategories == numTypes && numCategories == numColours
&& numCategories == numStyles && numCategories == numPrices) // ...
It would be nice if we could do the comparison like this:
if (a == b == c == d == e)
but obviously a == b resolves to a boolean so we can't compare that to c.
Is there a library function in the JDK or another utility library with maybe a signature somewhat like this?
static boolean areEqual(int... numbers)
then we could use it like so:
if (areEqual(a, b, c, d, e)) //...
I could easily write a function like this myself, but why reinvent the wheel if you don't have to?
Maybe there's another idiomatic way to accomplish this that I'm missing.
Using Streams, you can take advantage of some convenient methods to achieve your goal.
You can use Stream's or IntStream's distinct() combined with count() to find the number of unique elements:
For int variables:
if (IntStream.of(a,b,c,d,e).distinct().count() == 1) {
}
For reference type variables:
if (Stream.of(a,b,c,d,e).distinct().count() == 1) {
}
Another way, which is probably less efficient (but I'll keep it here since it's the first thing I thought about) is creating a Stream of all the elements you want to compare and then collecting them into a Set and checking the size of the Set is 1 (since Set doesn't allow duplicates) :
if (IntStream.of(a,b,c,d,e).boxed().collect(Collectors.toSet()).size() == 1) {
}
or
if (Stream.of(a,b,c,d,e).collect(Collectors.toSet()).size() == 1) {
}
for general Objects.
A naive option is to build methods that receives all the variables as varargs and compare them one after other. If one of them is different you will get false
public static boolean areEqual(int...nums)
{
for (int i = 0 ; i < nums.length - 1 ; ++i) {
if (nums[i] != nums[i + 1]) {
return false;
}
}
return true;
}
Uses
if (areEqual(a, b, c, d, e))
I like this approach. There's no auto-boxing and no magic numbers.
As per the documentation, it's also short-circuiting so therefore potentially more efficient than other methods. More importantly, it's very easy to read.
IntStream.of(a, b, c, d).allMatch(x -> x == e);
Credit to saka1029.
In logic expressions remaining part would be skipped if it is unnecessary
boolean b = false && checkSomething( something)
//checkSomething() doesn't get called
What is a good way to achieve the same with arithmetic expressions ?
int i = 0 * calculateSomethig ( something )
It is possible to add ifs before * . But is there a more elegant way to solve this problem? Without of adding much stuff into expression, so that expression itself would look as close to original as possible
Why i do not want to use ifs?
from
return calculateA() * calculateB()
it'll become bulky and unclear
int result
int a = calculateA();
if (a!=0) {
result = a*calculateB()
}else{
result = 0
}
return result
8 lines of code instead of 1,
those expressions might be more complex than a*b
those expressions represent business logic so i want to keep them
clear and easily readable
there might be whole bunch of them
Why do i bother with this at all?
Because calculation methods might be expensive
uses values form other places, where searches and sorts are happening
lots of those expressions can be executed at once ( after user event and user should see result "instantly"
P( *0 in expression ) >0.5
&& and || are called short-circuit operators because they don't evaluate if the JVM will find the value of the whole expression without evaluating the whole expression. For example, the JVM does not have to evaluate the second part of the following expression to tell it evaluates to true:
6 == (2 + 4) || 8 == 9
The JVM does not have to evaluate all of the following expression either to tell it evaluates to false:
9 == 8 && 7 == 7
The multiplication operator (*) is not a short-circuit operator. And so, it does not behave that way. You can do this as you mentioned using if statements. There is no predefined way to do this.
You can create a structure that uses lambdas to evaluate its arguments lazily:
class LazyMul implements IntSupplier {
private final IntSupplier [] args;
private LazyMul(IntSupplier[] args) {
//argument checking omitted for brevity :)
this.args = args;
}
public static LazyMul of(IntSupplier ... args) {
return new LazyMul(args);
}
#Override
public int getAsInt() {
int res = 1;
for (IntSupplier arg: args) {
res *= arg.getAsInt();
if (res == 0)
break;
}
return res;
}
}
Of course this is even longer but using it is as simple as LazyMul.of(this::calculateA, this::calculateB), so if you use it several times, it's better than having an if every time around.
Unfortunately with complicated (particularly nested) expressions readability suffers, but these are the limitations of Java as a language.
In groovy I can iterate through numbers using that simple syntax:
(1..10).each {
do_domething it
}
What is the shortest syntax to do that in Java? I am now exploring streams and I came up with such an idea:
IntStream.range(0, 10)
.forEach(do_domething());
It is even longer than the traditional way (below), but seems to be more concise.
for (int i = 0; i < 10; i++)
do_domething()
I am just curious if there is shorter and readable way of doing it. I don't know everything about Java so I am just asking, probably there is no such thing, but I would like to make sure.
If you need to use IntStream.range repeatedly in one class, you can reduce verbosity by using a static import:
import static java.util.stream.IntStream.range;
Then the syntax becomes
range(0, 10).forEach(...)
Beyond that, there's not much else I can suggest. In my view it is a bit ridiculous that we have to write for(int i = 0; i < n; i++) repeatedly, but at least it has the advantage of being instantly recognisable.
There are some major differences between those two that do not make them drop in replacements of each other.
A return from a regular for-loop will return from your method, but for the stream/lambda version it returns from the lambda function. See below.
for (int i = 0; i < 10; i++) {
if (i == 5) {
return;//returns from the whole method
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
return; //returns only from the lambda
}
}));
Another major difference is how the two code blocks interact with variables. For lambdas to interact with variables that our outside its scope, they need to be final. So the stream/lambda code below won't compile.
String x = "";
for (int i = 0; i < 10; i++) {
if (i == 5) {
x = "5";
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
x = "5"; //wont compile
}
}));
There might be other differences between the two. But for me that last one has caused problems that has lead me to continue using the regular for-loop.
If you want concise you can use a helper method.
public static void each(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
and then you can write
import static java.lang.System.out;
each(0, 10, out::println);
If "each" is a bit verbose you could use a connector character like
public static void ⁀(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
public static void main(String... args) {
⁀(0, 10, out::println);
}
prints
0
1
2
3
4
5
6
7
8
9
You could create a helper function to create an array
public static int[] range(final int length){
return IntStream.range(0, length).toArray();
}
Then using a foreach loop all you need to write is:
for(int i : range(10)) {
do_domething();
}
You can use the so-called "Facetious Arrow" operator (it looks like an arrow "-->") to write the loop slightly more briefly. [Pro Tip: It's not really an arrow]
for (int i=10;i-->0;)doSomething();
For example:
for (int i=10;i-->0;)System.out.println(i);
Prints:
9
8
7
6
5
4
3
2
1
0
I'm teaching programming to beginners (starting at 12-15 years old) and one of the choices we made (because it was natural in Python) was to teach the notion of "repeating an action" before the notion of variables.
We warted in Python with
for loop in range(10):
without speaking about variables of arrays and in C++ with
#define repeat(nb) for(int _loop = 0 ; _loop < (nb) ; _loop++)
The idea was to hide the complexity of a classical loop in order to insist on the "repeat" part. We are not hiding from the students the fact that "repeat(10)" is not a part of C++,
it's just a way to simplify the learning.
In Pascal we can't do much more than
for loop := 1 to 10 do
but that's ok because its's not that difficult to remember.
I was looking for something similar in Java and I found that :
import java.util.List;
import java.util.AbstractList;
class Range {
public static List<Integer> size(final int end) {
return new AbstractList<Integer>() {
#Override
public Integer get(int index) {
return 0 + index;
}
#Override
public int size() {
return end;
}
};
};
}
public class Main {
public static void main(String[] argv) {
for (int loop : Range.size(10)) {
System.out.println("xx");
}
}
}
The
for (int loop : Range.size(10))
is still easier to remember than
for(int loop = 0 ; loop < 10 ; loop++)
but there is two problems :
two variables are needed for imbricated for loops : I dont think we can do much about that
we are having warnings because the variable loop is not used
Do you see a better solution that what we have ?
Once again, we only want to provide some "tool" at the beginning phase in order for the students to "repeat" actions, before knowing anything about "variables". We are not hiding from them that's is not in the langage and after a few exercises (~80-100) we are asking them to use the real syntax.
We have approximately 20 exercices before introducing variables : some about printing texts but mostly we are providing one library with objects you can manipulate (hence the variables are hidden in the object state). You can think of the "logo-turtle" for example. This way the notion of "loop" can be manipulated and "seen" before introducing explicit variables and you can have interresting exercises really fast.
One example, in Python, where you want to visit every case of a 10x10 table once and only once and then be back at your starting point (lower-left corner) :
from robot import *
top()
for loop in range(4):
for loop in range(8):
top()
right()
for loop in range(8):
bottom()
right()
for loop in range(8):
top()
right()
for loop in range(9):
bottom()
for loop in range(9):
left()
This exercise is not that easy but the syntax is really simple and allow the student to concentrate on the "algorithmic" part and not the "langage" part.
After a few exercises the students are getting interrested and we can introduce more syntax and more difficult concepts like the variables.
Do you really need to use Java for those exercises? If other languages works for you then why not to use them? You can always move to Java when you students know basics like variables.
I agree that variables can be quite confusing from beginners - especially that their value can change all the time, it is not something people are used from algebra where values don't change once "assigned".
If you want to use Java, you could use while loop which seems to fit better. One dirty trick how to avoid use of variable is following code - it use StackTraceElement instead of variable.
It prints
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Hello A
Hello B
Hello C
Hello C
Hello C
Hello B
Hello C
Hello C
Hello C
Here is full source. main(Strinng[] args) method is code with loops, rest is supporting code.
import java.util.HashMap;
import java.util.Map;
public class Repeater {
public static void main(String[] args) {
while(range(3)) {
System.out.println("Hello A");
while (range(2)) {
System.out.println("Hello B");
while (range(3)) {
System.out.println("Hello C");
}
}
}
}
public static boolean range(int size) {
return Range.range(size);
}
public static class Range {
static Map<StackTraceElement, RangePosition> ranges = new HashMap<StackTraceElement, RangePosition>();
public static boolean range(int size) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3];
//System.out.println(stackTraceElement);
RangePosition position = ranges.get(stackTraceElement);
if (position == null) {
position = new RangePosition();
position.size = size;
ranges.put(stackTraceElement, position);
}
final boolean next = position.next();
if (!next) {
ranges.remove(stackTraceElement);
}
return next;
}
}
public static class RangePosition {
int current,size;
boolean next() {
current++;
return current <= size;
}
}
}
But I'd prefer to use some language which supports this naturally.
I would always introduce variables first. What are you going to do inside the loop without knowledge about variables ?
Apart from that maybe it would be easier to use a while loop. The head of a while loop is much easier and doesn't require variable definitions.
This is very simple to understand:
while (do_the_loop){
//this is repeated
}
Java really is not suitable for this kind of task because it does not allow for functions to be passed.
The only way I can think of doing this without variables would be with an interface:
private static void repeat(int times, DoStuff what) {
for (int i = 0; i < times; i++) {
what.doIt();
}
}
private interface DoStuff {
public void doIt();
}
And then use it this way:
repeat(5, new DoStuff() { public void doIt() {
System.out.println("xx"); // whatever needs to be done
}});
Which would be without variables but quite confusing at the beginning.
This is not really what you are searching for, but here is my opinion and how I would teach it. (Beware, I'm not a teacher at all :D)
Aren't there two different courses for this: Algorithms and Programming? In programming, you really should start off by teaching them the variables. It's not difficult at all. And I don't think that 20 exercises about algorithms are going to be that interesting for them. I think they will be more attracted to the power of computing something than either writing for loops inside each other. Writing a simple program that computes some summations and multiplications et cetera will do to introduce the idea of primitive variables. Then I would introduce the for loop. Demonstrate by printing 10 times some text in combination with the variable used in the for loop:
for (int i = 0; i < 10; ++i)
// Tell them that the 'i' is a variable as you explained before.
{
System.out.println("This is line " + i);
}
Then writing an application that computes the factorial of a hardcoded number will be interesting, I think. This way, most of them will hopefully get the idea of working with variables. Then try to explain scopes.
int number = 5;
int factorial = 1;
for (int i = 1; i <= number; ++i)
{
factorial = factorial * i;
}
System.out.println(number + "! = " + factorial);
if you have a limit defined you have to use a while structure
while(myval < mylimit){
//do something
myval++;
}
but when the limit is unknow then you should use for or for each
for (int i =0; i< list.size();i++)
{
}
of by objects
for each (String myString : myStringArray){
}
Saludos