I'm currently trying to create a randomly generated string. Problem is, with the way I have it setup it continues to add on to itself.
My code ( I'm calling a lot of static variables from another class so don't worry about that portion)
class Generate1 extends Thread{
#Override
public void run() {
while(RUNNING == true){
generate();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void generate(){
for(int i=0;i<length;i++){
int decider = rando.nextInt(6)+1;
if(decider == 1){
sb1.append("A");
}
if(decider == 2){
sb1.append("B");
}
if(decider == 3){
sb1.append("C");
}
if(decider == 4){
sb1.append("D");
}
if(decider == 5){
sb1.append("E");
}
if(decider == 6){
sb1.append("F");
}
}
Log.d("PSS",sb1.toString()); // this here is the stringbuilder being outputted
}
}
if I set length to 2, in my log it would look something like:
DF
DFCA
DFCAEF
instead of my desired output:
DF
CA
EF
how do I fix this? ( I know this is probably a stupid question but it's late and pondering through code hurts my eyes and brain )
edit - shmosel brought light to what was wrong. It was a really simple fix to me overlooking something
You're using the same StringBuilder instance for each call to generate(). Use a fresh one instead:
private void generate(){
StringBuilder sb1 = new StringBuilder(length);
// ...
}
Related
I wanted to make an input which accepts numbers from 1 - 10 and prints the range.
I need to check if the input is an integer (check), check if the range is 0-10 (check), and if it's not any of those things, to ask the user again. So, a recursive method?
Currently I have this:
import java.util.Scanner;
import java.util.InputMismatchException;
public class FinalTest {
public static void main (String [] args) {
Scanner in = new Scanner(System.in);
int k = 0;
System.out.print("int - ");
try {
k = in.nextInt();
} catch (InputMismatchException e) {
System.out.println("ERR: Input");
System.exit(1);
}
if(k <= 10 && k > 0) {
for(int j=1; j <= k; j++) {
System.out.println(j);
}
} else {
System.out.println("ERR: Oob");
System.exit(1);
}
}
}
I would like to replace the "System.exit()" so that it re attempts to ask the user for input again.
calling main(); produces an error.
How do I correctly call the main method in this case?
Two choices here:
actually create a method and call that
simply use a loop
Loop could go like:
boolean askForInput = true;
while ( askForInput ) {
try {
k = in.nextInt();
askForInput = false;
} catch ...
print "not a number try again"
}
But beyond that: you still want to put this code into its own method. Not because that code should call itself, but for clarity reasons. Like:
public static int askForNumber(Scanner in) {
... code from above
return k;
}
And to answer your question: you do not want to use recursion here. You want to loop; and yes, recursion is one way to implement looping, but that is simply overkill given the requirement you want to implement here.
And for the record: when creating that helper method, you can actually simplify it to:
public static int askForNumber() {
while ( askForInput ) {
try ...
return in.nextInt();
} catch ...
print "not a number try again"
}
}
Beyond that: you typically use recursion for computational tasks, such as computing a factorial, or fibonacci number, ... see here for example.
for the part of the recursive method printing a range:
public void printAscending(int n) {
if (n > 0) {
printAscending(n - 1);
System.out.println(n);
}
}
I think using recursion is just too much for something that simple and would probably be more expensive. You can add a while loop around your scanning bit until the entered value is valid. I would also put the printing loop out of the while to not have to test a condition before printing since if you get out of the while loop, it means number if valid. You could test just the -1 value to exit process.
public class FinalTest
{
public static void main (String [] args)
{
Scanner in = new Scanner(System.in);
int k = 0;
do
{
System.out.print("int - ");
try
{
k = in.nextInt();
}
catch (InputMismatchException e)
{
System.out.println("ERR: Input");
System.exit(1);
}
}
while(!(k>0 && k<=10) && k!=-1);
if(k!=-1)
{
for(int j=1; j<=k; j++)
{
System.out.println(j);
}
}
else
{
System.out.println("Bye Bye.");
}
}
}
Okay, so what I personally do when I need to use recursion is I create a separate function/method for it. And when I need to restart the method, I just call it within itself. So it would be something like this:
private void recursiveMethod() {
// do stuff . . .
if (yourCondition) {
//continue to next piece of code
} else {
recursiveMethod();
}
}
But in big projects, try to stay away from recursion because if you mess up, it can
I am being asked to learn Java very quickly and I am struggling with not only the verbose syntax but also the expected style and approach requirements.
Given a simple FizzBuzz challenge I produced the following code:
public class FizzBuzz {
public static void main(String[] args) {
boolean hit;
for (int n = 1; n <= 30; n++) {
hit = false;
if (n % 3 == 0) {
System.out.print("Fizz");
hit = true;
}
if (n % 5 == 0) {
System.out.print("Buzz");
hit = true;
}
if (hit != true) {
System.out.print(n);
}
System.out.println();
}
}
}
Asked to refactor this code by the lead programmer and to consider possible future requirements and code managability issues I gave it some thought and produced the following refactored code:
public class FizzBuzz {
public static void main(String[] args) {
boolean hit;
for (int n = 1; n < 30; n++) {
hit = false;
hit = (n % 3 == 0) ? writeAction("Fizz") : hit;
hit = (n % 5 == 0) ? writeAction("Buzz") : hit;
if ( ! hit)
System.out.print(n);
System.out.println();
}
}
private static boolean writeAction(String actionWord){
System.out.print(actionWord);
return true;
}
}
However, the guy who set this task has moved on quite quickly and I never got any feedback on this approach. Am I going in the right direction with this or have I regressed?. To me this should scale better and would be easier to modify. I have also considered that maybe he was expecting some sort of TDD approach? I am aware that I have no tests currently.
This site isn't for reviews, but in case your question gets moved, here is some feedback (from the "clean code" perspective):
your "main" code sits in a main() method. Makes re-using it very hard.
talking about re-use - various things in there prevent re-using it
you have some duplicated code in there
you are violating the single layer of abstraction principle
How I would write something along the lines of:
public class FizzBuzz {
private final OutputStream out;
public FizzBuzz(OutputStream out) {
this.out = out;
}
public void runFizzBuzzUpTo(int n) {
for (int i = 1; i < n; i++) {
if ( writeIfTrue(n % 3 == 0, "Fizz") ) {
continue;
}
if ( writeIfTrue(n % 5 == 0, "Buzz") ) {
continue;
}
out.println(n);
}
}
private boolean writeIfTrue(boolean toCheck, String word) {
if (toCheck) {
out.println(word);
}
return toCheck;
}
public static void main(String[] args) {
new FizzBuzz(System.out).runFizzBuzzUpto(30);
}
}
Things I changed:
made the output the "core" thing of a class
provided the possibility to run for arbitrary positive numbers
Stuff still missing:
"single layere of abstraction" is still not good
instead of fixing "30" in main() - one could check for exactly one argument passed to main() - which would then be used as parameter for runFizzBuzzUpTo()
Of course, the second code is more modular and easier to modify that way. I mostly don't prefer to write the if conditions in the short way...
The method writeAction could be void because you don't have to return anything.
But you have good ideas :)
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
I use if() sentences to control some transition, but it does not work. How can I solve these problems? I use the EasyFSM library to implement the simulation based on Finite State Machine.
I attach my own code. This is only the part of my code that has the problem I want to solve.
I think that there is no syntax error, but when I run the program there is no transition (the f.ProcessFSM(~) does not work) and there are only IDLE states (it is the first state of the FSM.)
How can I solve this problem?
FSM f = new FSM("C://Users//losin//Desktop//file//PMC.xml", new FSMAction() {
#Override
public boolean action(String curState, String message, String nextState, Object args) {
return true;
}
});
for(int j=0; j <10 ; j++) {
list.add(f.getCurrentState().toString());
if(f.getCurrentState().toString()=="IDLE") {
double rnd1 = Math.random();
if(list.contains("PROCESS_COMPLIETED")==true) {
if(rnd1 < 0.05) {
f.ProcessFSM("FAIL");
} else if(rnd1 < 0.15) {
f.ProcessFSM("CLEAN");
} else {
f.ProcessFSM("LOAD");
}
} else {
if(rnd1 < 0.05) {
f.ProcessFSM("FAIL");
} else {
f.ProcessFSM("LOAD");
}
}
} else if(f.getCurrentState().toString()=="PREPARE") {
f.ProcessFSM("PROCESS_START");
} else if(f.getCurrentState().toString()=="PROCESS") {
double rnd2 = Math.random();
if(rnd2 < 0.05) {
f.ProcessFSM("FAIL");
} else {
f.ProcessFSM("COMPLETE");
}
} else if(f.getCurrentState().toString()=="PROCESS_COMPLETED") {
f.ProcessFSM("UNLOAD");
} else if(f.getCurrentState().toString()=="FAILURE") {
f.ProcessFSM("FIX");
} else {
f.ProcessFSM("CLEAN_END");
}
}
CSVUtils.writeLine(writer, list);
writer.flush();
writer.close();
if(f.getCurrentState().toString()=="IDLE") //is wrong use
if(f.getCurrentState().toString().equals("IDLE"))
This condition is never correct
if(f.getCurrentState().toString()=="IDLE") {
you are comparing references and not the content of the object
String objects must be compared using the equals method
if("IDLE".equals(f.getCurrentState().toString()))
I am new to Java. I am trying to create a Java Program that has the ability to retry itself when an exception occur in the program (which work fine). Now the problem I have now is in the for loop. In this code, when something went wrong in the for loop, the program itself will jump out of that loop and go to the catch method. After that if the retry is less than MAX_RETRIES, then the program will relaunch from the beginning. This is what I am struggling with. What I want is let say if there is an exception occur in the for loop when printing let say 5, I want the program to retry where the exception in the for loop occur not relaunch from the beginning. Are there ways to do it? I am struggling with this for a while and cannot seems to find a way to do it. Help and code for reference will be appreciated. This is the best way I can think of to simplify my code. In my real application, the for loop I have right now is to Iterate though a list of record from the database.
main.java
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
try {
while (retry <= MAX_RETRIES) {
//method1
//stuff code
//more code
//method2
for (int i = 0; i < 11; i++) {
System.out.println("i");
}
}
System.out.println("-----Finish Process-----");
break;
} catch (Exception e) {
e.printlnStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
I think it solve your problem
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
//method1
//stuff code
//more code
//method2
int i=0;
while (i < 11) {
try {
System.out.println(i);
i++;
} catch (Exception e) {
e.printStackTrace();
i++;
if (i == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
retry++;
} catch (Exception e) {
e.printStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
System.out.println("-----Finish Process-----");
}
}
I have an idea that might help. I can't show any example code, but it might be possible to set up a flag/signal1 after you complete each step in executing the program. Then, when the program retries, it can automatically skip to that point in code where it last stopped.
1: I don't know what it's called in java
Since Java cannot unload native libraries when once used (in Matlab; see SO question), i am trying to call 2 GUI classes from within Matlab. I am working on grabbing an image from camera and then saving it on disk. I want to use one Java class for communicating with camera while another class (GUI) is still open in Matlab. Is this possible? Here's the code:
1.
public class GUI
{
public static void main(String[] args)
{
// Just open up the window and start things running
MainWindow mWindow = new MainWindow();
}
public static void main2()
{
MainWindow.grabImage(0);
}
}
2.
public class MainWindow
{
static volatile int commandVal;
Thread updateThread;
static CameraImage cImage;
static int fs_c =1;
MainWindow(){
JFrame main_f = new JFrame("M");
main_f.getContentPane().setLayout(new BorderLayout());
main_f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
main_f.getContentPane().add(tabPane1, "Center");
main_f.pack();
main_f.setVisible(true);
kkk = 1;
mySerial = new CameraSerial(cWindow.getPort());
}
}
3.
public static void grabImage(int commandVal){
while (MainWindow.kkk == 1) {
if (MainWindow.fs_c == 1) {
MainWindow.commandVal = 5;
}
if (MainWindow.commandVal == 5 || MainWindow.commandVal == 6){
cImage.sendFrame(0);
JFileChooser save_d = new JFileChooser();
File saveFile = save_d.getSelectedFile();
cImage.writeImage(saveFile + ".jpg");
MainWindow.fs_c = 0;
MainWindow.commandVal = 0;
mySerial.write("\r");
System.out.println("Camera Ready...");
break;
}
else if (commandVal == -1) {
MainWindow.commandVal = 0;
mySerial.write("\r");
status_t.setText("Camera Ready...");
}
else {
try {
Thread.sleep(100);
} catch (Exception e) {
}
}
}
}
From Matlab I'm calling first Gui.main([]), and then Gui.main2(). It works for the first time. But when I call Gui.main2() again, Matlab does nothing. I think it's a bad code somewhere. Thanks for replying!
Just an assumption without having more information:
This check:
if (MainWindow.fs_c == 1) {
MainWindow.commandVal = 5;
}
And later this (note that commandVal would be 5 after the check succeeded for the first time):
MainWindow.fs_c = 0;
MainWindow.commandVal = 0;
Here's the problem:
In the first run, commandVal is set to 5, assuming MainWindow.fs_c is initially 1.
Thus MainWindow.fs_c = 0; is executed.
In the second run MainWindow.fs_c == 1 is false (MainWindow.fs_c is now 0) and MainWindow.commandVal was also set to 0. Thus the method doesn't do anything, except sleeping for 100 milliseconds.