Printing job status only once based on the status - java

I'm new to Java and I would like to ask a more theoretical question. I'm trying to add a new feature on a working program which is written in Java. The purpose of the program is to run multiple jobs in the background and check their status. The status could be "Ready", "Waiting", "Running", "Stopped", "Done". I would like to create a method which will print some information to the output, which is based on the status of the running jobs. The rules for the printing:
For the first time of checking the job, it should print: "Started: " + job.getName().
If job is stopped it should print "Failed: " + job.getName().
If job is done running it should print "Done: " + job.getName().
In the job class I declared two variables:
private boolean startDisplay = false;
private boolean endDisplay = false;
I did a loop through all jobs and check their status and print the proper message for each case. Also, I updated the variables to be true. But the problem is it prints the same string over and over. So I made those variables static:
private static boolean startDisplay = false;
private static boolean endDisplay = false;
But, in this way it will print start and end for only one job (and not for the others).
How can I print every message only once? I thought of using the hashmap but it does not feel the right OOP way.

From What I guess you need a POJO class something like following :
package com.stackoverflow;
public class Job {
private String jobName;
private boolean startDisplay = false;
private boolean endDisplay = false;
private boolean doneDisplay = false;
public Job(String jobName) {
this.jobName = jobName;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public boolean isStartDisplay() {
return startDisplay;
}
public void setStartDisplay(boolean startDisplay) {
this.startDisplay = startDisplay;
}
public boolean isEndDisplay() {
return endDisplay;
}
public void setEndDisplay(boolean endDisplay) {
this.endDisplay = endDisplay;
}
public boolean isDoneDisplay() {
return doneDisplay;
}
public void setDoneDisplay(boolean doneDisplay) {
this.doneDisplay = doneDisplay;
}
}
And a Class to manage your POJO :
package com.stackoverflow;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
List<Job> jobs = new ArrayList<>();
for (int i = 0; i < 5; i++) {
jobs.add(new Job("Job" + (i+1)));
}
String prompt = "";
while (!prompt.equals("q")) {
Scanner scanner = new Scanner(System.in);
prompt = scanner.nextLine();
if (prompt.equals("q"))
System.out.println("Bye");
if (prompt.equals("1")) {
System.out.println("Checking Job1 " + jobs.get(0).getJobName());
System.out.println("Started: " + jobs.get(0).isStartDisplay());
System.out.println("Done: " + jobs.get(0).isDoneDisplay());
System.out.println("Finished: " + jobs.get(0).isEndDisplay());
System.out.println("Changing State of the job....");
jobs.get(0).setStartDisplay(true);
}
}
}
}

Try to declare the boolean variables with the volatile keyword. Otherwise the main thread will not reliably see the changes made by the other threads.

Related

Why does the counter inside if statement not work?

Hello friends I am trying to build a class Car for a project. There are many methods inside the following code as well as an if statement that I am having trouble building, consider the following code
public class Car extends Vehicle {
private boolean isDriving;
private final int horsepower;
private boolean needsMaintenance = false;
private int tripsSinceMaintenance = 0;
Car() {
super();
this.horsepower = 0;
this.isDriving = false;
this.needsMaintenance = false;
this.tripsSinceMaintenance = 0;
}
public int getHorsepower() {
return this.horsepower;
}
public boolean getDrive() {
return this.isDriving;
}
public boolean getMain() {
return this.needsMaintenance;
}
public int getTRIP() {
return this.tripsSinceMaintenance;
}
public void drive() {
this.isDriving = true;
}
public void stop() {
this.isDriving = false;
}
public void repair() {
this.needsMaintenance = false;
this.tripsSinceMaintenance = 0;
}
/**
* #param args
*/
public static void main(String[] args) {
Car auto = new Car();
auto.drive();
auto.stop();
if (auto.isDriving == true) {
if (auto.isDriving == false)
auto.tripsSinceMaintenance = auto.tripsSinceMaintenance + 1;
}
if (auto.tripsSinceMaintenance > 100)
auto.needsMaintenance = true;
System.out.println("Drive: " + auto.getDrive());
System.out.println("trip: " + auto.getTRIP());
}
}
What I want to do is whenever the attribute isDriving goes from true to false the tripsSinceMaintenance should increase by 1 and also when tripsSinceMaintenanceis greater than 100,needsMaintenanceshould becometrue`.
here I expected trips to be 1 but the result is the following:
Drive: false
trip: 0
I have tried this.isDriving==true; and basicaly wherever auto is inside the if statement I put this but the following error appears
non static variable cannot be referenced from static context
help me please!
What i want to do is whenever the attribute isDriving goes from true to false the tripsSinceMaintenance should increase by 1 and also when tripsSinceMaintenance is greater than 100 needsMaintenance should become true
Do this inside stop() method
fun stop() {
if (isDriving) {
tripsSinceMaintenance++;
}
if (tripsSinceMaintenance > 100) {
needsMaintenance = true;
}
isDriving = false;
}
You don't need to put == true inside of an if statement, it's doing that already,
if(someCondition) { // <-- this executes if the condition is true.
Also, you have conflicting conditions nested, meaning...
if (thisIsTrue) {
if (!thisIsTrue) {
// <--- unreachable statements
where you should be incrementing your variable is where you're setting "isDriving = true"
So your code would look like this:
public void drive() {
this.isDriving=true;
auto.tripsSinceMaintenance++;
}

How can I make it so that J grasp finds the main method in this blackjack game?

I am developing a blackjack game using java but after i got done (or almost done) writing the whole program J grasp says "No main methods, applets or MIDlets found in file." The code is below. How do i make J Grasp find the main method. If you notice any other thing that will keep the code from running, how would I fix those other things as well.
import java.util.*;
public class Blackjack{
private int points;
private int limit;
private Scanner scan;
private boolean firstTime;
private String response;
private int outcomeOfRoll;
//*******reminder to myself: the word void in the next line of code could be incorrect**********
public Blackjack(){
scan = new Scanner (System.in);
}
public void displayPoints(){
System.out.print("Your points: " + points + "/" + limit);
}
public void startGame () {
System.out.print("Enter point limit");
limit=scan.nextInt();
displayPoints();
}
public void Roll (){
Random randomRoll = new Random();
int outcomeOfRoll = randomRoll.nextInt(6)+1;
System.out.print("You rolled a " + outcomeOfRoll);
}
public String askUser (boolean firstTime){
String response = null;
if (firstTime== true){
System.out.print("Start playing?");
response = scan.next();
return response;
}
else {
System.out.print("Keep playing?");
response = scan.next();}
return response;
}
public void displayResult(){
if (points==limit)
System.out.print("Blackjack!");
else if (points>limit)
System.out.print("Bust!");
else if (points<limit)
System.out.print("Stand at " + points + " points!");
}
public void play(){
boolean gameOver = false;
startGame();
askUser(firstTime);
while(response.equals("yes") && gameOver==false){
points = points + outcomeOfRoll;
displayPoints();
if (points>=limit)
gameOver=true;
askUser(firstTime);
displayResult();
}
}
public void main(){
play();
}
}
In Java, you need to have a method named main in at least one class and it has to be public static void and takes an array of String as a parameter.
Main method in Java looks like this:
public static void main(String[] args)
just modify your main method to match it's signature exactly
for more information I suggest you to read documentation

Massive StackOverflowError from GSON toJson

So I am trying to use GSON to convert a class into a JSON file with the toJson() function and every time the code gets called there is a massive 1000+ line StackOverflowError. This is the error: http://pastebin.com/dBhYUFva
And here is the class I am doing gson.toJson() on:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import mc.kwit.arena.players.ArenaPlayer;
import mc.kwit.arena.util.PlayerUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Zach on 8/3/16.
*/
public class Match {
List<ArenaPlayer> arenaPlayers = new ArrayList<ArenaPlayer>();
String[] uuidArray = null;
Player winner;
String matchId = "123456";
int killLimit = 5;
int timeLimit = -1;
public Match() {
}
public Match(List<ArenaPlayer> arenaPlayerList, String id, int seconds, int kills) {
this.arenaPlayers = arenaPlayerList;
this.matchId = id;
this.timeLimit = seconds;
this.killLimit = kills;
}
public Match(String[] players, String id, int seconds, int kills) {
this.uuidArray = players;
this.matchId = id;
this.timeLimit = seconds;
this.killLimit = kills;
}
public void start() {
//Create our ArenaPlayer objects
this.arenaPlayers = PlayerUtil.uuidToArenaPlayerList(uuidArray);
Bukkit.getLogger().info("Match \" " + this.matchId + "\" has been started!");
//Whitelist all participants
for(ArenaPlayer p : arenaPlayers) {
KwitArena.pc.addArenaPlayer(p.getPlayer());
p.getPlayer().setWhitelisted(true);
Bukkit.getLogger().info(p.getName() + " has been whitelisted!");
p.setMatch(this);
}
}
public void finish() throws Exception {
//Remove all players from whitelist and game
for(ArenaPlayer p : arenaPlayers) {
p.getPlayer().setWhitelisted(false);
if(p.isWinner()){
p.kick(ChatColor.GREEN + "You have won the game!");
this.winner = p.getPlayer();
} else {
p.kick(ChatColor.RED + winner.getName() + "has won the game :(");
}
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String stats = gson.toJson(this);
KwitArena.postStats(stats);
//Remove this arena instance from the plugin
KwitArena.match = null;
}
public String getId(){
return(this.matchId);
}
public void setWinner(ArenaPlayer p) {
this.winner = p.getPlayer();
}
}
ArenaPlayer.class :
import mc.kwit.arena.Match;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
/**
* Created by Zach on 7/31/16.
*/
public class ArenaPlayer {
ArenaPlayer ap;
Player player;
OfflinePlayer offlinePlayer;
int kills = 0;
int deaths = 0;
boolean isInGame = false;
Match match = null;
boolean isWinner = false;
public ArenaPlayer(Player player){
this.player = player;
}
public ArenaPlayer(Player player, boolean playing, int numKills, int numDeaths) {
this.player = player;
kills = numKills;
deaths = numDeaths;
isInGame = playing;
}
//Getters
public String getMatchId() { return(this.match.getId());}
public int getKills() { return(this.kills);}
public int getDeaths() { return(this.deaths);}
public Match getMatch() { return(this.match);}
public Player getPlayer() { return(this.player);}
public String getName() { return(player.getName());}
public OfflinePlayer getOfflinePlayer() { return(this.offlinePlayer);}
//Setters
public void setMatch(Match match) { this.match = match;}
public void setIsWinner(boolean b) { this.isWinner = b;}
public void setOfflinePlayer(OfflinePlayer off) { this.offlinePlayer = off; }
//Extras
public void addDeath() { this.deaths++;}
public void addKill() { this.kills++;}
public boolean isPlaying() { return(this.isInGame);}
public boolean isWinner() { return(this.isWinner);}
public void kick(String message) { player.kickPlayer(message);}
}
I'm not really sure where to even begin in the stack trace, anyone have some pointers?
I think the problem is that Match has an ArenaPlayer field, and ArenaPlayer has a Match field, which if the two instances reference each other causes Gson to go into an infinite loop due to its implementation.
You'll have to detangle your classes, your instances, or use a different library, or exclude certain fields from serialization - see Gson doc.
BTW, 1000 is the default call stack depth - if you see this many lines in the stack, you've probably hit an infinite recursion.

state maintaining variable which goes back to the previous state after a time

Is it possible for a variable in java to revert back to its previous state after a time limit.For example:If I have a boolean variable say x which was initialized to false and later the value was changed to true.Is it possible for this variable to revert back to its original value (ie false) after a time limit.Can this be achieved without using a timer or are there any design patterns to achieve this functionality.
Find a small example of a class which keeps the state and based on the timeout it negates the state.
See this as a PoC. You might need to do some improvements for concurrent access or visibility if you want to use it in a multithreaded application.
public static void main(String[] args) throws Exception {
VolatileState volatileState = new VolatileState();
System.out.println("initial: " + volatileState.getState());
volatileState.setState(true, 5);
System.out.println("valid : " + volatileState.getState());
TimeUnit.SECONDS.sleep(10);
System.out.println("reset : " + volatileState.getState());
}
The class which keeps the state for a given time.
class VolatileState {
private long timeSet = Long.MAX_VALUE;
private long timeToLive = 0;
private boolean state;
/**
* Keep the given state for <code>timeToLife</code> seconds.
*/
void setState(boolean state, long timeToLive) {
this.timeSet = System.currentTimeMillis();
this.timeToLive = TimeUnit.MILLISECONDS.toSeconds(timeToLive);
}
boolean getState() {
if (System.currentTimeMillis() > timeSet + timeToLive ) {
state = !state;
System.out.println("state reset to " + state);
}
return state;
}
}
You can use something like this:
class RevertingBoolean {
private long timeToRevert = Long.MAX_VALUE;
private boolean value;
private boolean defaultValue;
void setDefaultValue(boolean value) {
this.defaultValue = value;
}
void setRevertAfter(long revertAfter) {
this.timeToRevert = System.currentTimeMillis() + revertAfter;
}
void setValue(boolean value) {
this.value = value;
}
boolean getValue() {
if (System.currentTimeMillis() > timeToRevert) {
this.value = this.defaultValue;
timeToRevert = Long.MAX_VALUE;
}
return this.value;
}
}
Usage:
RevertingBoolean myBool = new RevertingBoolean();
myBool.setDefaultValue(false);
myBool.setValue(false);
myBool.setRevertAfter(10000); // Revert value in 10 seconds
myBool.getValue(); // false
myBool.setValue(true);
myBool.getValue(); // true
// ... 10 seconds later ...
myBool.getValue(); // false
You can create a class, e.g., BooleanReverts, which has members for the new value, old value to which it reverts, and time to revert, and with setter methods that set up reversion. You probably want a separate thread to manage all the timers and execute callbacks to effect the reversion.
here is a simple generic class and a Test case with a boolean type (but you can use with any type) of a class that shoud match your requirements
package test;
public class TimeValueVar<T> {
private T originalValue;
private T currentValue;
private long duration;
private long creationTime;
public TimeValueVar(T value, long duration) {
originalValue=value;
currentValue=value;
this.duration=duration;
creationTime=System.currentTimeMillis();
}
public void set(T value) {
currentValue=value;
}
public T get() {
if ((System.currentTimeMillis()-creationTime)>duration) {
return originalValue;
}
return currentValue;
}
}
here is the test case
package test;
import java.util.concurrent.TimeUnit;
public class TesttimeBasedValue {
public static void main(String[] args) throws Exception {
long duration =2000;
TimeValueVar<Boolean> boolVal=new TimeValueVar<>(true,duration);
System.out.println("original: " + boolVal.get());
boolVal.set(false);
System.out.println("before duration : " + boolVal.get());
TimeUnit.MILLISECONDS.sleep(duration+1);
System.out.println("after duration : " + boolVal.get());
}
}

I am having troubles writing a test driver

my first time reaching out for help to solve a question, not sure what is causing the issue. I have these two classes I wrote, and the assignment asks me to make a test driver proving that the classes work.
Student Class:
public class Student{
private Course[] courseList;
private static int numCourses;
private final int maxCourses;
public Student(int max){
maxCourses = max;
courseList = new Course[numCourses];
numCourses = 0;
}
// part 1, done
public boolean addCourse(Course newClass){
boolean success = false;
for(int i=0; i<=maxCourses; i++){
if(i == numCourses){
courseList[i] = newClass;
success = true;
numCourses++;
}
}
return success;
}
// part 2, done
public boolean dropCourse(Course oldClass){
boolean success = false;
for(int i=0; i<=courseList.length; i++){
if (courseList[i] == oldClass){
courseList[i] = null;
numCourses--;
success = true;
}
}
return success;
}
// part 3, done.
public int getNumCourses(){
return numCourses;
}
//part 4, done
public boolean isFullTime(){
boolean success = false;
if (numCourses >= 3){
success = true;
}
return success;
}
// part 5, done
public String getClassList(){
String list = "";
for(int i=0;i<=numCourses; i++){
list = courseList[i].getID() + "\t" + courseList[i].getName() + "\n";
}
return list;
}
}
and a Course class:
public class Course{
private String name;
private int id;
private static int nextID = 200000;
public Course(String nameIn)
{
name = nameIn;
id = nextID;
nextID++;
}
public String getName(){
return name;
}
public int getID(){
return id;
}
}
For some reason if I make a test driver even one as simple as:
public class tester{
public static void main(String[] args){
Course one = new Course(Java);
}
}
I receive an error at my parameter saying cannot find symbol
javac tester.java
tester.java:6: error: cannot find symbol
one = new Course(name);
^
symbol: variable name
location: class tester
1 error
I had a much longer test driver but it did not make it past the first few lines as this was the same error just several of the same error.
Thanks for your time.
EDIT: I had put the Student class in twice by mistake, in my short test driver the only class in use is the Course class.
The problem is that because there are not quotes around Java, the compiler takes it as a variable name. Since it is undefined, the compiler cant find it. Use Course one = new Course("Java");

Categories