Changing a specific value from another class in java - java

Hi I'm trying to make a basic program that will increment a given number until it finds the next prime number, but I'm having problem making it work
PrimeNumber(long eNumb)
{
number= eNumb;
}
public static void incrementNumber()
{
this.number = number + 1;
}
boolean foundNext = false;
PrimeNumber findNext = new PrimeNumber(next);
while (!foundNext)
{
if (PrimeNumber.isPrime())
{
foundNext = true;
}
else
{
FindNext.incrementNumber();
}
}
I have the isPrime() method working, but I seem to be entering an infinite loop.
Sorry if the question is unclear
EDIT : I entered the wrong code, still wants answer though.

foundNext = true is always true, I think you have to make it false
any were in your program.
Suppose,
while (!foundNext) {
// foundNext = false; make it false on basis of any condtion
}

Problem liss here:
while (!foundNext) // it schould check if foundNext is prime number
Code can be simplified like so:
PrimeNumber(long eNumb)
{
this.number= eNumb;
}
public void incrementNumber()
{
this.number++;
}
... // some code here. I assume that code below is inside some method.
PrimeNumber findNext = new PrimeNumber(next);
while (!findNext.isPrime()) // in tis solution I assume that number is not static field
{
findNext.incrementNumber();
}

Related

Print numbers sequentially using two threads

This an interview question and i don't think it has any relation with practical real life problems.
I have to print numbers 12345.... sequentially but the condition is i have to print it using two threads one responsible for printing odd numbers and one for even numbers.
till now i have come up with this solution.
package junk.concurrency;
public class PrintEvenOddTester {
public static void main(String... args) {
TaskEvenOdd t = new TaskEvenOdd(10);
Thread t1 = new Thread(t, "odd printer");
Thread t2 = new Thread(t, "even printer");
t1.start();
t2.start();
}
}
class TaskEvenOdd implements Runnable {
private int max;
private boolean isOdd = true;
private int number = 1;
TaskEvenOdd(int max) {
this.max = max;
}
synchronized void printEven(int number) { // sync on runnable itself
while (isOdd) { // if odd is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Even:" + this.number); // LINE-1
isOdd = true;
this.number++; // LINE-2
notifyAll();
}
synchronized void printOdd(int number) { // sync on runnable itself
while (!isOdd) { // if even is to be printed, wait
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Odd:" + this.number); // LINE-3
this.number++; // LINE-4
isOdd = false;
notifyAll();
}
#Override
public void run() {
while (number <= max) {
if (Thread.currentThread().getName().equals("even printer")) {
printEven(number);
} else {
printOdd(number);
}
}
}
}
1
while writing this code i observed one strange behaviour which i did not understand. If at LINE-1,2,3,4 in above code, i write number instead of this.number my number instance variable is not getting incremented and code just prints infinite number of 1s.
I assume both the printEven and printOdd method is called on runnable instance itself then why its value is not getting incremented. I tried making number volatile but still it resulted in same output.
2
Also i see numbers are getting printed till 11 not till 10. I understand why this is happening(as the last call to printOdd gets notified by last call of printEven(which is printing 10) thus prints 11 ), one way to avoid this is to check number every time before printing and see if it's under limit but i wanted to know what would be the best way to overcome this.
Thanks.
EDIT method parameter number is completely redundant and can be omitted. This if(this.max>=number) condition can be used before printing the number.
1
Your problem is that the parameter of your method is called number too. So it is shadowing the field of your class! So, when you omit, you inc the parameter; which simply doesn't have any real effect!
There are two solutions to this problem:
a) simply avoid doing it (so, by convention avoid using the same names as parameters and fields).
b) use tooling that spots such problems and tells you about. For example, findbugs has explicit rule to tell you about shadowing. And probably IDE's can be told to warn about this, too. See here.
2
Given the fact that this is just a "simple" assignment ... in my opinion a simple check for the "limit" of the overall class would be just fine.

Smoother way to exit a void recursive Java function

So I wrote this function that behaves like Knuth's Algorithm X. Just for illustration - the function requires a large matrix of possible rows among which it tries to select the combination of the ones that make up for a legitimate solution.
The thing is, once we found the solution, since its void, the function doesn't return anything and instead just backtracks up (which consequently means it prints out sudoku for every level in the recursion depth).
Any suggestions on how to end the function the moment the solution is found? I am currently using System.exit(0) but that isn't nice since the program then ends the moment you find the solution (so anything you want to do afterwards is impossible - for example run the function on array of sudokus and solve each one).
The code is here:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
System.exit(0);
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
solve(solution, coverMatrix);
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
}
}
If I understand you correctly, you want to end recursion when you got the first solution. You can achieve this by having boolean return type for the method, and return true when you get first solution :.
public static boolean solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
return true;
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
boolean result = solve(solution, coverMatrix);
if(result == true) return result;//else continue
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
return false;
}
}
You can use the AtomicReference Class with a Boolean:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix, AtomicReference<Boolean> test) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
test.set(true);//System.exit(0);
}
solve(solution, coverMatrix, test);
if(!test.get())
{
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
You can call your method like this(just initialize the Boolean to false):
public static void main(String[] args)
{
AtomicReference<Boolean> test1 = new AtomicReference<Boolean>();
test1.set(false);
solve(***, ***, test1);
}
You could misuse the concept of exceptions for that, although I would not recommend it.
First define a custom exception class.
public class SuccessException extends Exception {}
Throw an instance on success.
if (Arrays.equals(solvedCase, workCase)) {
drawSudoku(testOutput);
throw new SuccessException();
}
Call the function initially in a try block.
try {
solve(solution, coverMatrix);
} catch(SuccessException e) {
/* Solution found! */
}

How to remove if else condition from loop?

I have a code snippet similar to the one below,
public ArrayList getReport(reportJDOList,accountType)
{
String abc = "";
for(ReportJDO reportJDO : reportJDOList)
{
if(accountType.equals("something")
abc = reportJDO.getThis();
else
abc = reportJDO.getThat();
//somecode goes here
}
returning List;
}
As I know the value of accountType before the iteration, I dont want this check to happen, for every entry in a list as it would cause numerous number of checks if the size of reportJDOList is 10000 for an instance. How we remove this thing from happening? Thanks in Advance :)
You can indeed peform check once and implement 2 loops:
if(accountType.equals("something") {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThis();
}
} else {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThat();
}
}
Obviously you can improve your design by either
separating you loops into 2 different methods
Using command pattern, i.e. implementing loop body in different command and executing it to loop.
Using Guava's Function (it is just improvement of #2)
Using java 8 streams.
IF you want to save the String comparison, make it once before the loop and store the result in a boolean variable :
String abc = "";
boolean isThis = accountType.equals("something");
for(ReportJDO reportJDO : reportJDOList) {
abc = isThis ? reportJDO.getThis() : reportJDO.getThat();
//somecode goes here
}
I'd vote for clean coding this - perform the check once and delegate the logic into private methods, each performing the loop individually. This duplicates code for the loop but gives greatest flexibility if at some point you need to do something more in SomethingReport that's not duplicated in OtherReport.
public ArrayList getReport(reportJDOList,accountType) {
if("soemthing".equals(accountType)) {
return getSomethingReport(reportJDOList);
} else {
return getOtherReport(reportJDOList);
}
}
private ArrayList getSomethingReport(reportJDOList) {
[...]
}
interface AccountHandler {
String get(Report r);
}
AccountHandler thisHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThis();
}
};
AccountHandler thatHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThat();
}
};
//...............
AccountHandler ah;
ah = (what.equalsIgnoreCase("this")) ? thisHandler : thatHandler;
Report r=new Report();
// loop
ah.get(r);
//Using reflection:
Report r = new Report();
Method thisMethod = r.getClass().getDeclaredMethod("getThis");
Method thatMethod = r.getClass().getDeclaredMethod("getThat");
Method m = (what.equalsIgnoreCase("this")) ? thisMethod : thatMethod;
m.invoke(r);

Populating a Boolean Array in Java

As a fairly green Java coder I've set myself the hefty challenge of trying to write a simple text adventure. Unsurprisingly, I've encountered difficulties already!
I'm trying to give my Location class a property to store which exits it contains. I've used a boolean array for this, to essentially hold true/false values representing each exit. I'm not entirely convinced that
a) this is the most efficient way to do this and
b) that I'm using the right code to populate the array.
I would appreciate any and all feedback, even if it is for a complete code over-haul!
At present, when instantiating a Location I generate a String which I send through to the setExits method:
String e = "N S U";
secretRoom.setExits(e);
In the Location class, setExits looks like this:
public void setExits(String e) {
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
else if (e.contains("S"))
bexits[2] = true;
else if (e.contains("E"))
bexits[3] = true;
else if (e.contains("U"))
bexits[4] = true;
else if (e.contains("D"))
bexits[5] = true;
}
I'll be honest, I think this looks particularly clunky, but I couldn't think of another way to do it. I'm also not entirely sure now how to write the getExits method...
Any help would be welcome!
The most efficient and expressive way is the following:
Use enums as Exits and use an EnumSet to store them. EnumSet is an efficient Set implementation that uses a bit field to represent the enum constants.
Here is how you can do it:
public enum Exit { North, West, South, East, Up, Down; }
EnumSet<Exit> set = EnumSet.noneOf(Exit.class); // An empty set.
// Now you can simply add or remove exits, everything will be stored compactly
set.add(Exit.North); // Add exit
set.contains(Exit.West); // Test if an exit is present
set.remove(Exit.South); //Remove an exit
Enum set will store all exits in a single long internally, so your code is expressive, fast, and saves a lot of memory.
Is there any reason why you are doing this with Strings and aren't passing in booleans, i.e.
public void setExits(boolean N, boolean E, boolean S, boolean W, boolean U, boolean D)
Or having setters?
public void setNorthOpen(boolean open)
{
bexits[4] = open;
}
Secondly, why are you storing the exits as an array of booleans, it's a small finite set, why not just
boolean N,S,E,W,U,D;
As then you don't need to keep track of which number in the array each direction is.
Also
This is a correct answer (if not completely optimal like that of #gexicide) but I fully encourage anyone to look at the other answers here for an interesting look at how things can be done in Java in different ways.
For future reference
Code which works belongs on Code Review, not Stack Overflow. Although as #kajacx pointed out, this code shouldn't -in fact- work.
OK, first of all, your setExits() method will not work as intended, chained if-elseif will maximally execute 1 branch of code, for example:
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
Even if e contains both N and W, only bexits[0] will be set. Also this method will only add exits (for example calling setExits("") will not delete any existing exits.
I would change that method to:
bexits[0] = e.contains("N");
bexits[1] = e.contains("W");
...
Also, i definetly wouldn't remember that north is on index 0, west in on 1, ... so a common practice is to name your indexes using final static constants:
public static final int NORTH = 0;
public static final int WEST = 1;
...
Then you can write in your setExits method:
bexits[NORTH] = e.contains("N");
bexits[WEST] = e.contains("W");
...
(much more readible)
Finally, if you want your code even more well-arranged, you can make a Exits class representing avaliable exits, and backed by boolean array. Then on place where you create your String, you could create this class instead and save yourself work with generating and then parsing a string.
EDIT:
as #gexicide answers, there is a really handy class EnumSet which would be probably better for representing the exits than bollean array.
The EnumSet in the other answer is the best way to do this, I just wanted to add one more thing though for the future when you start looking not just at whether you can move but where you are moving to.
As well as EnumSet you also have EnumMap.
If you define a Room class/interface then inside the Room class you can have
Map<Direction, Room> exits = new EnumMap<>(Direction.class);
You can now add your links into the map as follows:
exits.put(Direction.NORTH, theRoomNorthOfMe);
Then your code to move between rooms can be very general purpose:
Room destination=currentRoom.getExit(directionMoved);
if (destination == null) {
// Cannot move that way
} else {
// Handle move to destination
}
I would create an Exit enum and on the location class just set a list of Exit objects.
so it would be something like:
public enum Exit { N, S, E, W, U, D }
List<Exit> exits = parseExits(String exitString);
location.setExits(exits);
Given what your code looks like, this is the most readable implementation I could come up with:
public class Exits {
private static final char[] DIRECTIONS = "NSEWUD".toCharArray();
public static void main(String... args) {
String input = "N S E";
boolean[] exits = new boolean[DIRECTIONS.length];
for(int i = 0; i< exits.length; i++) {
if (input.indexOf(DIRECTIONS[i]) >= 0) {
exits[i] = true;
}
}
}
}
That being said, there's a number of cleaner solutions possible. Personally I would go with enums and an EnumSet.
By the way, your original code is incorrect, as it will set as most one value in the array to true.
If you're defining exits as a string, you should use it. I would do it like:
public class LocationWithExits {
public static final String NORTH_EXIT="[N]";
public static final String SOUTH_EXIT="[S]";
public static final String EAST_EXIT="[E]";
public static final String WEST_EXIT="[W]";
private final String exitLocations;
public LocationWithExits(String exitLocations) {
this.exitLocations = exitLocations;
}
public boolean hasNorthExit(){
return exitLocations.contains(NORTH_EXIT);
}
public static void main(String[] args) {
LocationWithExits testLocation=new LocationWithExits(NORTH_EXIT+SOUTH_EXIT);
System.out.println("Has exit on north?: "+testLocation.hasNorthExit());
}
}
using array of booleans might cause a lot of problems if you forget what exactly means bexits[0]. Os it for north or south? etc.
or you can just use enums and list of exits available . Then in methid test if list contain a certain enum value
Personally, I think you can hack it around a bit using an enum and turn the following:
public void setExits(String e) {
if (e.contains("N"))
bexits[0] = true;
else if (e.contains("W"))
bexits[1] = true;
else if (e.contains("S"))
bexits[2] = true;
else if (e.contains("E"))
bexits[3] = true;
else if (e.contains("U"))
bexits[4] = true;
else if (e.contains("D"))
bexits[5] = true;
}
into
public enum Directions
{
NORTH("N"),
WEST("W"),
SOUTH("S"),
EAST("E"),
UP("U"),
DOWN("D");
private String identifier;
private Directions(String identifier)
{
this.identifier = identifier;
}
public String getIdentifier()
{
return identifier;
}
}
and then do:
public void setExits(String e)
{
String[] exits = e.split(" ");
for(String exit : exits)
{
for(Directions direction : Directions.values())
{
if(direction.getIdentifier().equals(exit))
{
bexits[direction.ordinal()] = true;
break;
}
}
}
}
Although after having written it down, I can't really tell you if it's that much better. It's easier to add new directions, that's for sure.
All the approaches listed in the answeres are good. But I think the approach you need to take depends on the way you are going to use the exit field. For example if you are going to handle exit as strings then Ross Drews approach would require a lot of if-else conditions and variables.
String exit = "N E";
String[] exits = exit.split(" ");
boolean N = false, E = false, S = false, W = false, U = false, D = false;
for(String e : exits){
if(e.equalsIgnoreCase("N")){
N = true;
} else if(e.equalsIgnoreCase("E")){
E = true;
} else if(e.equalsIgnoreCase("W")){
W= true;
} else if(e.equalsIgnoreCase("U")){
U = true;
} else if(e.equalsIgnoreCase("D")){
D = true;
} else if(e.equalsIgnoreCase("S")){
S = true;
}
}
setExits(N, E, S, W, U, D);
Also if you have an exit and you want to check whether a location has that particular exit then again you will have to do the same
public boolean hasExit(String exit){
if(e.equalsIgnoreCase("N")){
return this.N; // Or the corresponding getter method
} else if(e.equalsIgnoreCase("E")){
return this.E;
} else if(e.equalsIgnoreCase("W")){
return this.W;
} else if(e.equalsIgnoreCase("U")){
return this.U;
} else if(e.equalsIgnoreCase("D")){
return this.D;
} else if(e.equalsIgnoreCase("S")){
return this.S;
}
}
So if you are going to manipulate it as a string, in my opinion the best approach would be to go for list and enum. By this way you could do methods like hasExit, hasAnyExit, hasAllExits, hasNorthExit, hasSouthExit, getAvailableExits etc etc.. very easily. And considering the number of exits (6) using a list (or set) wont be an overhead. For example
Enum
public enum EXIT {
EAST("E"),
WEST("W"),
NORTH("N"),
SOUTH("S"),
UP("U"),
DOWN("D");
private String exitCode;
private EXIT(String exitCode) {
this.exitCode = exitCode;
}
public String getExitCode() {
return exitCode;
}
public static EXIT fromValue(String exitCode) {
for (EXIT exit : values()) {
if (exit.exitCode.equalsIgnoreCase(exitCode)) {
return exit;
}
}
return null;
}
public static EXIT fromValue(char exitCode) {
for (EXIT exit : values()) {
if (exit.exitCode.equalsIgnoreCase(String.valueOf(exitCode))) {
return exit;
}
}
return null;
}
}
Location.java
import java.util.ArrayList;
import java.util.List;
public class Location {
private List<EXIT> exits;
public Location(){
exits = new ArrayList<EXIT>();
}
public void setExits(String exits) {
for(char exitCode : exits.toCharArray()){
EXIT exit = EXIT.fromValue(exitCode);
if(exit != null){
this.exits.add(exit);
}
}
}
public boolean hasExit(String exitCode){
return exits.contains(EXIT.fromValue(exitCode));
}
public boolean hasAnyExit(String exits){
for(char exitCode : exits.toCharArray()){
if(this.exits.contains(EXIT.fromValue(exitCode))){
return true;
}
}
return false;
}
public boolean hasAllExit(String exits){
for(char exitCode : exits.toCharArray()){
EXIT exit = EXIT.fromValue(exitCode);
if(exit != null && !this.exits.contains(exit)){
return false;
}
}
return true;
}
public boolean hasExit(char exitCode){
return exits.contains(EXIT.fromValue(exitCode));
}
public boolean hasNorthExit(){
return exits.contains(EXIT.NORTH);
}
public boolean hasSouthExit(){
return exits.contains(EXIT.SOUTH);
}
public List<EXIT> getExits() {
return exits;
}
public static void main(String args[]) {
String exits = "N E W";
Location location = new Location();
location.setExits(exits);
System.out.println(location.getExits());
System.out.println(location.hasExit('W'));
System.out.println(location.hasAllExit("N W"));
System.out.println(location.hasAnyExit("U D"));
System.out.println(location.hasNorthExit());
}
}
Why not this if you want a shorter code:
String symbols = "NWSEUD";
public void setExits(String e) {
for (int i = 0; i < 6; i++) {
bexits[i] = e.contains(symbols.charAt(i));
}
}
If you want a generic solution you can use a map, which maps from a key (in your case W, S, E.. ) to a corresponding value (in your case a boolean).
When you do a set, you update the value the key is associated with. When you do a get, you can take an argument key and simply retrieve the value of the key. This functionality does already exist in map, called put and get.
I really like the idea of assigning the exits from a String, because it makes for brief and readable code. Once that's done, I don't see why you would want to create a boolean array. If you have a String, just use it, although you might want to add some validation to prevent accidental assignment of strings containing unwanted characters:
private String exits;
public void setExits(String e) {
if (!e.matches("[NSEWUD ]*")) throw new IllegalArgumentException();
exits = e;
}
The only other thing I would add is a method canExit that you can call with a direction parameter; e.g., if (location.canExit('N')) ...:
public boolean canExit(char direction) {
return exits.indexOf(direction) >= 0;
}
I like enums, but using them here seems like over-engineering to me, which will rapidly become annoying.
**Edit**: Actually, don't do this. It answers the wrong question, and it does something which doesn't need to be done. I just noticed #TimB's answer of using a map (an EnumMap) to associate directions with rooms. It makes sense.
I still feel that if you only need to track exit existence, a String is simple and effective, and anything else is over-complicating it. However, only knowing which exits are available isn't useful. You will want to go through those exits, and unless your game has a very plain layout it won't be doable for the code to infer the correct room for each direction, so you'll need to explicitly associate each direction with another room. So there seems to be no actual use for any method "setExits" which accepts a list of directions (regardless of how it's implemented internally).
public void setExits(String e)
{
String directions="NwSEUD";
for(int i=0;i<directions.length();i++)
{
if(e.contains(""+directions.charAt(i)))
{
bexits[i]=true;
break;
}
}
}
the iterative way of doing the same thing..
Long chains of else if statements should be replaced with switch statements.
Enums are the most expressive way to store such values as long as the efficiency is not a concern. Keep in mind that enum is a class, so creation of a new enum is associated with corresponding overhead.

How to better structure the code

I was wondering on how to go about creating a quiz environment inside of android. What I do not want is to open up a new activity every time someone gets the answer correct because there is over 100 questions.
I am using g a radio group for thr answers a textview for the questions and a button to get to the next question,
So for now my code looks something like this
String questions[] = {"question1" , "question2".....};
If (textview.gettext= "question1" && radioA.is selected= true) {
RadioA.setText ("newAnswerHere");
RadioB.setText("......)
}
Now I know I can use a switch statement but there has to be an easier way to do this? Is there not?
I always recommend the simplest pattern: extract method
First step
String questions[] = {"question1", "question2".....};
if (isQuestion1Selected()) {
setNewAnswersHere()
}
private boolean isQuestionSelected() {
return textview.gettext().equals("question1") && radioA.isSelected == true;
}
private void setNewAnswersHere(){
RadioA.setText("newAnswerHere");
RadioB.setText("......);
}
But this is just first step :)
Second step
String questions[] = {"question1", "question2".....};
if (isQuestionSelected(1)) {
setNewAnswersHere()
}
private boolean isQuestionSelected(int number) {
return textview.gettext().equals("question" + number) && radioA.isSelected == true;
}
private void setNewAnswersHere(){
RadioA.setText("newAnswerHere");
RadioB.setText("......);
}
Have you tried using a "Question" object?:
public class Question {
String question;
String[] answers;
String correct;
//methods
}
Using that, you could store them in a data object and then use those instead of fixed arrays

Categories