How can I pass code into a method without it running first? - java

Please help as how can I achieve below in java.
public class TestUserFunctions {
public static boolean equals(int val1, int val2){
if(val1==val2){
return true;
} else{
return false;
}
}
public static Object iterateValue(String ittr, int iterations){
for(int i=1; i <= iterations; i++){
System.out.println("Printing iteration #"+i);
}
return ittr;
}
private static void ifElse(boolean condition, Object returnstr, Object elsestr){
if(condition){
System.out.println("TRUE");
//Need a code here which will iterate string value only once.
} else{
System.out.println("FALSE");
//Need a code here which will iterate string value thrice as specified.
}
}
public static void main(String[] args){
ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));
}
}
I may be wrong in many aspect here with my above code. I am sorry for that.
The expected output here is
TRUE
Printing iteration #1
In case of ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3)); the expected output is
FALSE
Printing iteration #1
Printing iteration #2
Printing iteration #3

The point is:
ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));
In Java, all method arguments get evaluated (aka computed) before the invocation takes place.
In other words:
equals(1,1) will always result in true
thus always the first "Value" is returned (although that doesn't really matter; as you are using the same value in both cases)
as said, both calls to iterateValue() will be executed; that means that this method is invoked twice, with the respective arguments for each call.
So, if you want to call iterateValue() only once; you should not use it as parameter. Instead, go for something like:
ifElse(equals(1,1), "ValueA", "ValueB"));
and then call iterateValue() on the first or second incoming String argument directly; and only once.

You need to defer execution of the if and else block using Java 8 lambda expressions to obtain what you want to achieve
import java.util.function.Supplier;
public class TestUserFunctions {
public static Supplier<Boolean> equals(int val1, int val2){
if(val1==val2){
return () -> true;
} else{
return () -> false;
}
}
public static Supplier<String> iterateValue(String ittr, int iterations){
return () -> {
for(int i=1; i <= iterations; i++){
System.out.println("Printing iteration #"+i);
}
return ittr;
};
}
private static void ifElse(Supplier<Boolean> condition, Supplier<String> returnstr, Supplier<String> elsestr){
if(condition.get()){
System.out.println("TRUE");
returnstr.get();
} else{
System.out.println("FALSE");
elsestr.get();
}
}
public static void main(String[] args){
ifElse(equals(1, 1), iterateValue("Value", 1), iterateValue("Value", 3));
}
}
Using Java < 8 the readability is greatly decreased
interface Supplier<T> {
public T get();
}
public class TestUserFunctions {
public static Supplier<Boolean> equals(int val1, int val2){
if(val1==val2){
return new Supplier<Boolean>() {
public Boolean get() { return true; }
};
} else{
return new Supplier<Boolean>() {
public Boolean get() { return false; }
};
}
}
public static Supplier<String> iterateValue(String ittr, int iterations){
return new Supplier<String>() {
public String get() {
for(int i=1; i <= iterations; i++){
System.out.println("Printing iteration #"+i);
}
return ittr;
};
};
}
private static void ifElse(Supplier<Boolean> condition, Supplier<String> returnstr, Supplier<String> elsestr){
if(condition.get()){
System.out.println("TRUE");
returnstr.get();
} else{
System.out.println("FALSE");
elsestr.get();
}
}
public static void main(String[] args){
ifElse(equals(1, 2), iterateValue("Value", 1), iterateValue("Value", 3));
}
}

Your problem can be expressed more succinctly like this:
public class Demo() {
static int x = 0;
static int incrementAndReturnX() {
x++;
return x;
}
static void ifElse(boolean predicate, int t, int f) {
if(predicate) {
return t;
} else {
return f;
}
}
static void main(String... args) {
System.out.println(ifElse(false, incrementAndReturnX(), incrementAndReturnX());
}
}
This prints 2.. Why is this, and how can we make it return 1?
The answer is the order in which Java calls methods. When it deals with ifElse(true, incrementAndReturnX(), incrementAndReturnX()), it runs the methods passed as parameters, so as to get an object or a primitive. Then it invokes ifElse().
So:
Java notes that true is a primitive. Nothing to do. Move on.
Java calls incrementAndReturnX(). x is incremented. 1 is returned.
Java calls incrementAndReturnX() again. x is incremented. 2 is returned.
Java uses the values it has collected to call ifElse(false, 1, 2)
You can see that the result of this is 2.
What we need is some way of passing a method to the ifElse() routine, as if it was an object, so that it can choose whether to run it or not. In Java 7, the only way we could do that was by creating classes containing our methods, so we could pass them around.
interface IntegerSupplier() {
int get();
}
...
final int[] x = new int[1];
IntegerSupplier incrementAndReturnX = new IntegerSupplier() {
x[0] += 1;
return x[0];
};
Note this is using anonymous class syntax. We are creating a new class here, and creating an instance of it, without giving it a name.
We are also wrapping x in an array, because the inner class can only refer to final variables, and we need to be able to modify the value.
public int ifOrElse(boolean predicate, IntegerSupplier t, IntegerSupplier f) {
if(true) {
return t.get();
} else {
return f.get();
}
}
The key here is that the code that increments x is in a method that's not called until inside the if block.
As of Java 8, we have a much neater way of doing the same thing. We can very succinctly declare something very like our IntegerSupplier using what is called a lambda:
Supplier<Integer> incrementAndReturnX = () {
x[0]++;
return x;
}
public int ifOrElse(boolean predicate, Supplier<Integer> t, Supplier<Integer> f) {
if(true) {
return t.get();
} else {
return f.get();
}
}
(java.util.function.Supplier is provided by the JRE: we don't need to declare our own)
This whole way of thinking is called functional programming, and is very powerful and expressive.

Related

Is there an alternative to using 'this' in this code?

I have the following code snippets and would like to know how 'this' is being used as well as if there is another way of doing it with same end result. I tried generating an ArrayList by doing, ArrayList a = new ArrayList();, but it did not include the numbers '1, 2' and only have '4,6'. The output should be '1, 2, 4, 6'.
I am highlighting the code I am asking about:
int i = 0;
Sequence a = this;
Methods:
import java.util.ArrayList;
public class Sequence
{
private ArrayList<Integer> values;
public Sequence()
{
values = new ArrayList<Integer>();
}
public void add(int n)
{
values.add(n);
}
public String toString()
{
return values.toString();
}
public Sequence append(Sequence other)
{
int i = 0;
Sequence a = this;
while(i < other.values.size())
{
a.add(other.values.get(i));
i++;
}
return a;
}
}
Tester/Driver:
public class SequenceTester
{
public static void main(String[] args)
{
Sequence obj2 = new Sequence();
obj2.add(4);
obj2.add(6);
Sequence obj = new Sequence();
obj.add(1);
obj.add(2);
Sequence append = obj.append(obj2);
System.out.println(append);
}
}
would like to know how 'this' is being used
"this" refers to the current instance of a class.
if there is another way of doing it with same end result.
There is no need to explicitly create a Sequence variable in the append(...) method.
You can just invoke the add(...) method directly and return "this":
public Sequence append(Sequence other)
{
int i = 0;
//Sequence a = this;
while(i < other.values.size())
{
//a.add(other.values.get(i));
add(other.values.get(i));
i++;
}
// return a;
return this;
}
Methods of the class always operate on the current instance of the class so there is no need to use "this" to get a reference to the class.

Why I can't use "return" in my code at Java?

I have a problem with my Java Code at the fourth line.
I have this error: "this method must return a result of type int".
So I didn't return 'c'. How can I return?
public class bese_bolunme {
static int function(int b)
{
for (int c=0;c<b;c++)
{
if(c%5==0)
{
System.out.println(c);
return c;
}
}
}
public static void main(String[] args) {
function(36);
}
Since you declared in your function signature that it returns an Integer, you must, in all execution flows of your function return an Integer.
static int function(int b)
{
for (int c=0;c<b;c++)
{
if(c%5==0)
{
System.out.println(c);
return c;
}
} //end for loop
return -1; //Or other logic you prefer
}
On every execution path in the method function(int b) a return statement must be reached. You are taking care of not all paths: I.e. what should the method return in case of not entering the for loop?

Make a new function (method) that takes two doubles as input and return the biggest one

I don't understand how to make two doubles as input and return the biggest number.
Make a new function (method) that takes two doubles as input and return the biggest one.
My solution (trying an if-statement):
public class ex1DoubleFunction {
public static void main(String[] args) {
double a = 10;
double b = 20;
System.out.println(doublefun(a, b));
public static doublefun(a,b) {
if (a>b) {
return a;
}
else if (a<b) {
return b;
}
}
}
}
This is also consider if you have equals value.
public static double whichGreater(double first, double second) {
if(first >= second){
return first;
} else {
return second;
}
}
This is a very simple task, the solution below should do.
public static double findMax(double numOne, double numTwo){ // parameters
return Math.max(numOne,numTwo); // built in class to find the max of two nums or more
}
Also, make sure you don't put this function inside the main method because it won't work. put this inside the same class as the main method for simplicity.
This should work.
public static double doublefun(double a, double b) {
if ( a > b) {
return a;
} else {
return b;
}
}
You can also use ternary operator.
return (a>b)?a:b;

How to block attributes from being used in java

Basically I would like to know if there is a way to "disable" an attribute within a block after a certain point.
For example check the following scenario:
for(int i=0;i<10;i++){
for(int j=i+5;j<50;j++){
//from here until end of the block I want to make sure I don't use **i** anymore.
print(j*5+i); //I want this line to produce compiler error
}
}
Don't get me wrong I understand it is a bad programming, but I still can't help but to use i,j,k,h as attributes. and sometimes I make a mistake by misplacing the attributes in wrong places.
Call a method.
for (int i = 0; i < 10; i++) {
for (int j = i + 5; j < 50; j++) {
doSomething();
}
}
...
private void doSomething() {
// Woot, no i and no j!
}
Your code doesn't make sense to anybody. You need to divide it into functions with good names so that anyone can understand what your program is doing without comments around the code or getting mixed up with variables.
Here's an example for the code you have posted:
public void printNumberTimes5(int number) {
print(number*5);
}
But don't stop there, make it obvious what the loop is doing too:
public void printSomeNumbers(int someNumber) {
for(int j=someNumber+5;j<50;j++){
printNumberTimes5(j);
}
}
And again:
public void printSomeNumbers_repeat(int repeat) {
for(int i=0;i<repeat;i++){
printSomeNumbers(i);
}
}
I don't really know what you're doing but renaming the function to what you're supposed to be doing would make it clear.
Remember: each function should only have one job.
Finally, give i and j real names so that you understand what those numbers do and don't mix them up.
The best way to obtain this in java, is by using scope. Make sure that the variables are in different scopes and then you don't have access to it. A good guideline to follow is to split your logic in various small methods, this way you'll ensure the desired behavior.
My recommendations in order of preference:
Use meaningful variable-names. Maybe i isn't as good as e.g. row, ...
Use functions to group operations and also reduce the variables they can access. This can also lead to a point where repeating operations can easily be reused.
Use a custom counter-object like this one
/**
* Created for http://stackoverflow.com/q/25423743/1266906
*/
public class ObliviousLoops {
public static void main(String[] args) {
for(LockableCounter i = new LockableCounter(0); i.getValue() < 42; i.unlock().increment()) {
System.out.println("A-loop:" + i.getValue());
i.lock();
// No access, everything is fine
}
for(LockableCounter i = new LockableCounter(0); i.getValue() < 42; i.unlock().increment()) {
System.out.println("B-loop1:" + i.getValue());
i.lock();
// Next statement will throw an Exception
System.out.println("B-loop2:" + i.getValue());
}
}
static class LockableCounter {
private long value;
private boolean locked;
LockableCounter(long value) {
this.value = value;
}
public LockableCounter lock() {
this.locked = true;
return this;
}
public LockableCounter unlock() {
this.locked = false;
return this;
}
public long getValue() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
return value;
}
public void increment() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
value++;
}
#Override
public String toString() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
return String.valueOf(value);
}
}
}
the most obvious draw-backs of the last solution is a less fluent handling of the value, less ways to optimize the operations for the compiler, ... in practice you may even want to replace the LockableCounter by something different, once you are sure you calculations are written as desired to speed things up.
Use Java 8's lambda-function to build something behaving similar to for-loops where you can null-out the counter for the rest of the cycle (actually this is a variant of #2)
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* Created for http://stackoverflow.com/q/25423743/1266906
*/
public class LambdaLoops {
public static void main(String[] args) {
iterate(0, 42, (i) -> {
System.out.println("A-loop:" + (i + 0));
i = null;
});
iterate(0, (i) -> i < 42, (i) -> ++i, (i) -> {
System.out.println("B-loop:" + (i + 0));
i = null;
});
iterate(0, (i) -> i < 42, (i) -> {
System.out.println("C-loop1:" + (i + 0));
i = null;
// Next statement will not throw an Exception
System.out.println("C-loop2:" + i);
// Next statement will throw an Exception
System.out.println("C-loop3:" + (i + 0));
});
}
static void iterate(Integer initial, Integer limit, Consumer<? super Integer> function) {
for (Integer i = initial; i < limit; i++) {
function.accept(i);
}
}
static void iterate(Integer initial, Predicate<? super Integer> when, Consumer<? super Integer> function) {
for (Integer i = initial; when.test(i); i++) {
function.accept(i);
}
}
static <T> void iterate(T initial, Predicate<? super T> when, Function<? super T, ? extends T> increment, Consumer<? super T> function) {
for (T i = initial; when.test(i); i = increment.apply(i)) {
function.accept(i);
}
}
}
as in #3 this will most likely lead to decreased performance, but has the advantage, that your IDE might alert you, that i will always be null. This should however be easier to optimize be inlining than #3 as there is no additional boolean involved. If and when the JIT does inlining is however hard to guess.
Since so many of answers talk about why this is a bad idea, so I won't repeat it.
One solution that comes to my mind is to use an counter object. Whenever you want a particular counter to go out of scope, set that to null. If you use it after this point, a Null pointer access warning is shown (at least in eclipse. I suspect other IDEs should also have this feature. Not sure whether javac generates a warning).
public class DisappearingVariables {
public static class Counter {
int i = 0;
public Counter() {
}
public void inc() {
i++;
}
public int get() {
return i;
}
}
public static void main(String[] args) {
for(Counter i = new Counter(), oi = i; i.get() < 10; i = oi, i.inc()) {
System.out.println("i = " + i.get());
i = null;
i.inc(); // This line gets a warning
for(int j = 0; j < 10; j++) {
}
}
}
}

Recursion - incrementing a number and returning

Ok, this must be something really stupid....my statement is returning 2:
When I print out the values they are all correct
The return statement is wrong somehow
Code:
public static void main (String [] args)
{
System.out.println(countToTen(1));
}
public static int countToTen(int last_answer){
last_answer++;
if(last_answer != 10){
countToTen(last_answer);
}
return last_answer;
}
Try replacing your if statement with:
if(last_answer != 10){
return countToTen(last_answer);
}
Without the return statement, the recursive calls do get executed, but the calculated result is never returned.
The order of calls with your broken code looks like:
countToTen(1)
-> countToTen(2)
--> countToTen(3)
---> more calls to countToTen()
--- ... --> countToTen(10) // do nothing, and return to the top-level method call
-> return 2 // 2 because you incremented it using lastAnswer++
Your function returns the value from the first call. It is the initial value (1) incremented once by the ++ statement, so the function returns 2.
Integers are passed by value in Java, incrementing the passed value inside the function does not change the value outside:
int x = 0;
v(x);
// x still 0 here.
void v(int x) {
x = 100;
}
Try this:
public static int countToTen(int last_answer){
last_answer++;
if(last_answer != 10){
return countToTen(last_answer);
}
else {
return last_answer;
}
}
If you want to print out 1,2,3,4 ... 10, you need to print out the answer in every phase separately
public static void main (String [] args){
countToTen(1);
}
public static void countToTen(int last_answer){
System.out.println(last_answer);
last_answer++;
if(last_answer <= 10){
countToTen(last_answer);
}
}
My proposal
public static int countToTen(int last_answer){
last_answer++;
if(last_answer < 10){
return countToTen(last_answer);
} else {
return last_answer;
}
}
You are not passing the argument by reference, it is a copy. You are doing a modification in last_answer in the context of method, but this change is not propagate outside, because in the end you return last_answer++
public static void main (String [] args)
{
System.out.println(countToTen(1));
}
public static int countToTen(int last_answer)
{
last_answer++;
if(last_answer != 10)
{
return countToTen(last_answer); //Here was the error
}
return last_answer;
}

Categories

Resources