Break from called method in java - java

I have two methods:
public void test() {
for (int i = 0; i <= 10; i++) {
a();
}
}
public void a() {
// ...
}
Suppose the test method is fixed, I can not modify it.
How can I break the for loop in the a method?

You can throw an unchecked exception.
Another solution is to sub-class the class which has the first method and fix it so it can stop early e.g. if a() return true.

You can throw an exception, or you could simply use break;. This is a little less work, as you don't need to handle an exception at all.
Example:
public class Test
{
public static void main(String[] args)
{
foo();
}
public static void foo()
{
int i = 0;
for(i = 0; i <= 10; i++)
{
System.out.println("in loop: " + i);
if(i == 5) break;
}
System.out.println("end value: " + i);
System.out.flush();
}
}
The end value of i will be 5.

Related

Exchange values between classes/Methods

i recently learned the use of public, private and double in my different classes. But for some reason i cant understand why this is not working. My intention was to use three different classes as an exercise: I want Do() to make numbers from 0 to 20 and show only the numbers 0 till 10 on my console using the method for1() in a different class. Can someone please fix this issue? I dont need a shorter code or a code in just 1 class since i need it to educate myself using many classes. I would thank anyone if you could fix this issue using this kind of setup. Thanks in advance.
public class MainM {
public static void main(String[] args) {
loop Q = new loop();
Q.Do();
}
}
//------------------------------------------------------
public class loop {
public double b;
Sum R = new Sum(); // Java shows the problem is here : at Sum.<init>(Sum.java:3)
public void Do() {
for (int i = 0; i < 10; i++) {
b = b + 2;
if (b <= 10) {
R.for1();
}
}
}
}
//--------------------------------------------------
public class Sum {
loop Q = new loop();
public void for1() {
System.out.println("b " + Q.b);
}
}
You can have your Sum class only with the print statement and the method for1() should have one parameter. Bellow is my suggestion
public class Sum {
public void for1(double b) {
System.out.println("b " + b);
}
}
And your loop class will be
public class loop {
public double b;
Sum R = new Sum();
public void Do() {
for (int i = 0; i < 10; i++) {
b = b + 2;
if (b <= 10) {
R.for1(b);
}
}
}
}

Function value always getting multiplied by 2

I have created a function "m7" in my class but this function is always returning value getting multiplied by 2.
If I am running this function in "psvm" it is printing the right value.
In my Alice class, the method m7() is returning 10 which is incorrect but if I am running this method in psvm then it is returning 5 which is correct.
package com.math.functions;
import java.util.*;
public class Alice {
Integer[] rank= new Integer[7];
Integer n=65;
int count=0;
public Alice() {
rank[0]=100;
rank[1]=100;
rank[2]=90;
rank[3]=80;
rank[4]=75;
rank[5]=60;
rank[6]=n;
//rank[6]=20;
//rank[7]=10;
//rank[8]=n;
Arrays.sort(rank, Collections.reverseOrder());
}
public void print() {
for (Integer a : rank) {
System.out.println(a);
}
}
public int m7() {
for (int i = 0; i < rank.length; i++) {
if (rank[i] == n) {
break;
}
count++;
}
return count;
}
public void res(){
int s = m7();
System.out.println("this is the value of s here :"+s);
Set<Integer> hash_Set = new HashSet<>();
for(int i=0;i<=s/2;i++){
System.out.println("hii");
hash_Set.add(rank[i]);
}
for(Integer o:hash_Set){
System.out.println(o);
System.out.println("rank:"+hash_Set.size());
}
}
public static void main(String[] args) {
Alice a=new Alice();
a.print();
System.out.println("this is: "+a.m7());
a.res();
}
}
You are reusing the value of count from the previous time you run it.
Don't declare count as a member variable, make it a local variable.
public int m7() {
int count = 0; // HERE
for (int i = 0; i < rank.length; i++) {
if (rank[i] == n) {
break;
}
count++;
}
return count;
}

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++) {
}
}
}
}

Java For Loop into Recursive function

public class For {
public static void main(String[] args){
for(int i=2; i<=1024; i *= 2){
System.out.println("Count is: " + i);
}
}
public class While {
public static void main(String[] args){
int i = 1;
while (i < 1024) {
i *= 2;
System.out.println("Count is: " + i);
}
}
public class DoWhile {
public static void main(String[] args){
int i = 1;
if (i < 1024) {
do { i*=2;
System.out.println("Count is: " + i);
} while (i < 1024);
}
}
How would one convert the for loop/while loop so it does the same thing, but using a recursive function?
Like so:
public class Recursive {
public void r(int i) {
if (i < 1024) {
i *= 2;
System.out.println("Count is: " + i);
r(i);
}
}
public static void main(String[] args) {
Recursive r = new Recursive();
r.r(1);
}
}
Take the loop of main and put it in its own function with an argument int i. In that function, rewrite the loop to
If the loop condition is false (i >= 1024), then return
Else, recursive call with argument i*2.
Call the function with argument 1 or 2, depending on which of your programs you're rewriting (they don't entirely match).
Recurrent loop can look like this:
class Main
{
public static void main(String[] args){
RecWhile(1);
}
public static void RecWhile(int i) {
if (i < 1024) {
i = i*2;
System.out.println("Count is: " + i);
RecWhile(i);
}
}
}
public class Test1 {
public static void main(String[] args) {
Test1 mainFunc = new Test1();
int[] arr = {1,2,4,3,5,6};
int start=0;
int end=arr.length;
mainFunc.callRecursiveFun(start, end, arr);
}
public int callRecursiveFun(int start, int end, int[] arr) {
int arrLen = end;
if(arrLen == 0) {
return 0;
} else {
System.out.println("Loop Index at "+start +": "+arr[start]);
}
return callRecursiveFun(start+1, end-1, arr);
}
}

Write a program to accept number from command line and display sum of digits in a number by using recursive funcion

I have written the code but it displays Stackoverflowerror message.
class Sum
{
int ans=0,temp,temp2;
int getsum(int no)
{
if(no>0)
{
temp=no % 10;
ans=ans + temp;
getsum(no/10);
}
else
{
return ans;
}
}
}
class recsum
{
public static void main(String args[])
{
Sum s=new Sum();
int no,len;
len=args.length;
if(len==0)
{
System.out.println("No argruments are given ! ");
}
else
{
no=Integer.valueOf(args[0]).intValue();
System.out.println("Sum of digits= " + s.getsum(no));
}
}
}
You are over-complicating things a lot in your code. Here is a simpler working example:
public static int getSum(final String[] args, final int index) {
if (index < args.length) {
return Integer.valueOf(args[index]) + getSum(args, index + 1);
} else {
return 0;
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("You need to provide numbers as arguments.");
}
final int sum = getSum(args, 0);
System.out.println("Sum: " + sum);
}
You are supposed to be recursive, this is in the getSum function, because it is calling itself with differing parameters.
In recursive functions, you always need to have an exit branch that causes the calling to stop.
As sums won't change if you add 0 this can be exploited for a very clean exit.
The Stack overflow is normally because you never bottom out of the recursion.
Change class Sum to this:
class Sum {
int ans = 0, temp = 0;
int getsum(int no) {
if((no/10)-.5 >= 1)
ans += getsum(no/10);
else
return ans;
}
}
I'm not completely sure if this will work, and I can't compile it right now. I think this is one way to do it, but again, I'm not completely sure.
Program: Write a program to use Command Line Arguments.
class Sumnum1
{
int i,t,num,sum=0;
void getData(String s)
{
num=Integer.parseInt(s);
}
int digitSum()
{
for(i=num;i>=1;i=i/10)
{
t=i%10;
sum=sum+t;
}
return sum;
}
public static void main(String arg[])
{
int ds=0;
Sumnum1 obj=new Sumnum1();
obj.getData(arg[0]);
ds=obj.digitSum();
System.out.println("sum of digit="+ds);
}
}
BY :ANKIT AGRAWAL (A.A.)

Categories

Resources