Just trying to run through some code for an assignment I'm doing. It is probably simple but for the life of me I can't figure out why I get the above error at the first line
(public WaterLog.......).
Later I want to pass it this line:
[ log = new WaterLog(8, damCapacity); ]
Any help would be appreciated, I am new to this sorry.
public class WaterLog(Integer windowSize, Integer maxEntry) {
private Integer size = windowSize;
private Integer max = maxEntry;
private ArrayList theLog(int windowSize);
private int counter = 0;
public void addEntry(Integer newEntry) throws SimulationException {
theLog.add(0, newEntry);
counter++;
}
public Integer getEntry(Integer index) throws SimulationException {
If (thelog.isEmpty() || thelog.size() < index) {
return null;
}
return thelog.get(index);
}
public Integer variation() throws SimulationException {
int old, recent = 0;
recent = thelog.get(0);
old = thelog.get(thelog.size-1);
return recent-old;
}
public Integer numEntries() {
return counter;
}
}
Assuming SimulationException is defined correctly:
class WaterLog{
private Integer size;
private Integer max ;
private ArrayList<Integer> theLog; //parameterize your lists
private int counter = 0;
public WaterLog(Integer windowSize, Integer maxEntry) //this is the behavior you were looking for
{
this.size = windowSize;
this.max = maxEntry;
theLog = new ArrayList<Integer>(windowSize);
}
public void addEntry(Integer newEntry) throws SimulationException {
theLog.add(0, newEntry);
counter++;
}
public Integer getEntry(Integer index) throws SimulationException {
if (theLog.isEmpty() || theLog.size() < index) { //Java is case sensitive
return null;
}
return theLog.get(index);
}
public Integer variation() throws SimulationException {
int old, recent = 0;
recent = theLog.get(0);
old = theLog.get(theLog.size()-1); //again, watch case, also size is a method
return recent-old;
}
public Integer numEntries() {
return counter;
}
}
See the comments I added.
EDIT: To explain a bit further what was going on, let's take a look at what you were doing.
public class WaterLog(Integer windowSize, Integer maxEntry) {
private Integer size = windowSize;
private Integer max = maxEntry;
private ArrayList theLog(int windowSize);
private int counter = 0;
You seem to have confused a class with a constructor. The variables you defined were attributes, which was correct. You needed to use the syntax I showed in my answer to create a constructor. For that same reason, you don't have access to variables like windowSize. To remedy this, we allow them to still be defined outside the constructor, but assigned values inside it, where we have access to windowSize and maxEntry.
If you want to pass some parameters to this class you need a constructor. By default Each and EVERY class comes with a default constructor - which is there, you just don't see it ( but can declare it). What you can then do is make an overloaded construcotr ( which takes some arguments ) and this is what you want so..
if you have a class
class WaterLog {
// no constructor
}
the above is really a
class WaterLog {
public WaterLog() {
// this is the constructor - if you do not declare it its still here, you just dont see it. Ofcourse you have option to declare it.
}
}
The overloaded constructor is something like this
class WaterLog {
public WaterLog() {
//default constructor
}
public WaterLog(Integer int, String string, etc...) {
//overloaded constructor
}
}
and the above is what you need in order to pass arguments to this class constructor. I am not briliant at explaining things but if you need more clarification just let me know :)
Related
My class has a scheduled method that runs every half a second and it checks the data to see if any of the devices have timed out. If they are timed out for at least 5 seconds I am throwing an event to my database (this is done by checkSpecs method which I haven't reproduced here. The actual class is quite large so I have attempted to reduce the size while keeping relevant parts).
Now I am adding a new method to the class, checkReconnections which I want to use to throw another event to the database whenever a connection that previously timed out is regained.
Because my class is so large and I am monitoring several devices with this method, I attempted to create a helper method monitorConnectionStatus that accepts two booleans as arguments. My question is concerning this method.
I was under the impression that in passing the instance variables into monitorConnectionStatus when the method is invoked, that method gains access to them and can reassign those variables. This is my intent in order for the method to function as intended. But my IDE is telling me that the value of disconnectionStatus will always be false, which caused me to think, am I wrong in believing the instance variable will be reassigned? Is it possible that my IDE is just wrong in this case?
When I reassign the value of disconnectionStatus is it reassigning the value of the instance variable hasADisconnected or is it just doing it with a local argument variable?
Public Class OffSpecAgent {
private final DataModel dataModel;
private int deviceATimeoutCounter = 0;
private boolean isDeviceATimeout = false;
private boolean hasADisconnected = false;
private int deviceBTimeoutCounter = 0;
private boolean isDeviceBTimeout = false;
private boolean hasBDisconnected = false;
#Scheduled(fixedDelay = 500)
public void offSpecMonitor() {
checkTimeouts();
checkReconnections();
checkSpecs();
}
private void checkTimeouts() {
deviceATimeoutCounter = dataModel.getBoolean(DEVICE_A_TIMEOUT) ? deviceATimeoutCounter + 1 : 0;
isDeviceATimeout = deviceATimeoutCounter >= 10;
deviceBTimeoutCounter = dataModel.getBoolean(DEVICE_B_TIMEOUT) ? deviceBTimeoutCounter + 1 : 0;
isDeviceBTimeout = deviceATimeoutCounter >= 10;
}
private void checkReconnections() {
monitorConnectionStatus(isDeviceATimeout, hasADisconnected);
monitorConnectionStatus(isDeviceBTimeout, hasBDisconnected);
}
private void monitorConnectionStatus(boolean timeoutCondition, boolean disconnectionStatus) {
if (timeoutCondition) {
disconnectionStatus = true;
}
if (disconnectionStatus && !timeoutCondition) {
disconnectionStatus = false;
//throw reconnection event
}
}
}
In java, variables are passed by value into methods, meaning your method monitorConnectionStatus is only aware that it's getting false, false values. You would have to update your method to access the instance variable directly.
private void monitorConnectionStatus() {
if (this.timeoutCondition) {
this.disconnectionStatus = true;
}
if (this.disconnectionStatus && !this.timeoutCondition) {
this.disconnectionStatus = false;
//throw reconnection event
}
}
Note the keyword this is not required.
Also, I just want to add that you are using the term class variable incorrectly. The variables you are referring to are instance variables.
You can read more about that here:
https://www.tutorialspoint.com/What-are-class-variables-instance-variables-and-local-variables-in-Java
I refactored the class and now it looks like this:
Public Class OffSpecAgent {
private final DataModel dataModel;
private static class ConnectionTracker {
boolean timeout, timeoutExceeded, hasDisconnected;
int timeoutCounter = 0;
}
private final ConnectionTracker deviceATracker = new ConnectionTracker();
private final ConnectionTracker deviceBTracker = new ConnectionTracker();
#Scheduled(fixedDelay = 500)
public void offSpecMonitor() {
checkTimeouts();
checkReconnections();
checkSpecs();
}
private void checkTimeouts() {
trackTimeout(plcTracker, dataModel.getBoolean(DEVICE_A_TIMEOUT), 10);
trackTimeout(plcTracker, dataModel.getBoolean(DEVICE_B_TIMEOUT), 20);
}
private void trackTimeout(ConnectionTracker tracker, boolean isTimeout, int maxTimeout){
tracker.timeout = isTimeout;
tracker.timeoutCounter = isTimeout ? tracker.timeoutCounter + 1 : 0;
tracker.timeoutExceeded = tracker.timeoutCounter >= maxTimeout;
}
private void checkReconnections() {
monitorConnectionStatus(deviceATracker);
monitorConnectionStatus(deviceBTracker);
}
private void monitorConnectionStatus(ConnectionTracker tracker) {
if (tracker.timeoutExceeded) {
tracker.hasDisconnected = true;
}
if (tracker.hasDisconnected && !tracker.timeout) {
tracker.hasDisconnected = false;
//throw reconnection event
}
}
}
This seems to be much of an improvement, the tracker object actually makes the code more readable in my opinion, and now I am able to have the desired behavior. Thank you to everyone who responded to my question.
I was writing this piece of code to understand reflection and encountered one scenario where I couldn't really figure out the reason for the codes' behavior. Hopefully I receive some guidance from the community.
Following is my test model class & here, for every instantiation, I want to know the exact number of instances created during runtime (using reflection)
public final class Model {
private static final Model instance = new Model("Testing");
private static int count = 0;
private String name;
private Model(String name) {
this.name = name;
++count;
}
public static Model getInstance() {
return instance;
}
public static int getInstanceCount() {
return count;
}
public String getName() {
return name;
}
public void doSomething() {
try {
System.out.println("Shh.... I am trying to do something");
Thread.sleep(1000);
System.out.println("Ok! Done.");
return;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Oops! I failed in doing your job...");
}
}
The driver code for this scenario is as follows,
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Model.getInstance().doSomething();
System.out.println(Model.getInstanceCount());
Constructor<?>[] constructor = Model.class.getDeclaredConstructors();
for (Constructor<?> aConstructor : constructor) {
aConstructor.setAccessible(true);
Model m = (Model) aConstructor.newInstance("Testing through Reflection");
System.out.println(m.getName());
m.doSomething();
System.out.println(m.getInstanceCount());
//System.out.println(Model.getInstanceCount());
}
}
}
The output for this above piece of code came out to be as follows,
Shh.... I am trying to do something
Ok! Done.
0
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
1
As you can see, the instance count came out to be 1. I expected it to be as 2.
However, I changed the test model class's constructor as shown below. The datatype of count is now changed to Integer, instead of previously set 'int'.
private Model(String name) {
this.name = name;
if (count == null)
count = 0;
++count;
}
Surprisingly, I get the correct value for the instance count.
Shh.... I am trying to do something
Ok! Done.
1
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
2
This might be a silly question, but I am not able to ponder on what really happened behind the scenes. I need some guidance from the community on this.
Thanks in advance.
This has nothing to do with reflection.
private static final Model instance = new Model("Testing");
private static int count = 0;
The initializers are executed in order. So:
private static final Model instance = new Model("Testing");
Executing the constructor causes count to be incremented from 0 to 1, but then:
private static int count = 0;
Sets count back to zero.
Reverse the order of the declarations.
private static int count = 0;
private static final Model instance = new Model("Testing");
Or omit the initializer on count (its default value is zero anyway).
private static final Model instance = new Model("Testing");
private static int count;
I got a class used in an Android app, which is declared like this:
public static class MyData implements Comparable<MyData>
{
public MyEnum myEnum;
#Override
public int compareTo(MyData another)
{
if(this.myEnum.equals(MyEnum.Value1))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value1))
{
return -1;
}
if(this.myEnum.equals(MyEnum.Value2))
{
return 1;
}
if(another.myEnum.equals(MyEnum.Value2))
{
return -1;
}
return 0;
}
}
I defined a list: List<MyData> myList = new LinkedList<MyData>();
After adding items to the list I call: Collections.sort(myList)
The problem is that when I debug, I see the compareTo method being called after the sort method is invoked, however it doesn't enter the first if even that it should. I even put the Boolean expression in Eclipse in the "Expressions" view and it returned true, but the code simply jumps to the return 0; and the list is not being sorted like I want to.
Why is that?
Eventually I changed that enum class member to an int member which was initialized with the ordinal value inside the Enum.
Then the compareTo method was changed like this:
#Override
public int compareTo(MyData another)
{
Integer myVal = this.intVal;
Integer otherVal = another.intVal;
return myVal.compareTo(otherVal);
}
sorry for asking such basic question. I am trying some hands on ENUM. below is my code. I am getting some compilation error . Any idea where is the problem. I want SAMPLEMAIL,BULKUSERS,ALLUSERS should be of integer type.
public enum EmailSendingOption {
SAMPLEMAIL, BULKUSERS, ALLUSERS;
private int emailSendingOptionType;
private EmailSendingOption(String optionType) {
int value = Integer.parseInt(optionType.trim());
emailSendingOptionType = value;
}
public int getEmailSendingOption() {
return emailSendingOptionType;
}
}
thanks.
You have defined a constructor but you haven't supplied arguments for each of your Enums.
Looks like your constructor should take an integer too. Saves having to parse a String each time. It's also safer.
e.g.
SAMPLEMAIL(10), etc.
With your constructor looking like:
private int emailSendingOptionType;
private EmailSendingOption(int optionType) {
this.emailSendingOptionType = optionType;
}
You need to make it like this:
public enum EmailSendingOption {
SAMPLEMAIL("1"), BULKUSERS("2"), ALLUSERS("3");
private int emailSendingOptionType;
private EmailSendingOption(String optionType) {
int value = Integer.parseInt(optionType.trim());
emailSendingOptionType = value;
}
public int getEmailSendingOption() {
return emailSendingOptionType;
}
}
enum are not integers in Java, they are objects. There is no sane reason you would pass an integer as a String to a constructor so it can be parsed into an integer. If you want an integer use an integer.
public enum EmailSendingOption {
SAMPLEMAIL(1), BULKUSERS(2), ALLUSERS(101);
private final int emailSendingOptionType;
private EmailSendingOption(int emailSendingOptionType) {
this.emailSendingOptionType = emailSendingOptionType;
}
public int getEmailSendingOption() {
return emailSendingOptionType;
}
}
Since you are providing a custom constructor to your Enum
EmailSendingOption(String optionType)
You need to add those parameter for each Enum constant.
Change it to:
public enum EmailSendingOption
{
SAMPLEMAIL("String"), BULKUSERS("String"), ALLUSERS("String");
...
}
You defined a constructor as needed a String as argument. SAMPLEMAIL this are a static object
of EmailSendingOption.
I have a load of images of musical symbols which I need to do some processing on and for each one I need to get the integer code corresponding to its file name. There are 23 possible file name strings and 23 integer code and there are many images with the same name under different directories.
The solution I have so far is given (abbreviated) below. I have just defined a load of int and String constants and then written a method which is just a huge chain of if statements to do the translation.
What would be a better way to achieve the same effect? The way I've done it seems really awful! I thought about using some kind of Map, but I wasn't sure of the best way to do so.
public class Symbol {
public static final int TREBLE_CLEF = 0;
public static final int BASS_CLEF = 1;
public static final int SEMIBREVE = 2;
// ...
public static final String S_TREBLE_CLEF = "treble-clef";
public static final String S_BASS_CLEF = "bass-clef";
public static final String S_SEMIBREVE = "semibreve";
// ...
public static int stringCodeToIntCode(String strCode) {
if (strCode == S_TREBLE_CLEF) {
return TREBLE_CLEF;
} else if (strCode == S_BASS_CLEF) {
return BASS_CLEF;
} else if (strCode == S_SEMIBREVE) {
return SEMIBREVE;
} //...
else {
return -1;
}
}
}
I think you are looking for Enum where you can have String constant and its value.
Example:
public enum YourEnumClass{
STRING_CONST (5),
STRING_CONST2 (7),
.....
//constructor
//getValue() method
}
read linked tutorial for more details.
enum StringToInt{
TREBLE_CLEF(0),
......
}
Enum is the way to go.
Another example:
public enum Color {
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
private int code;
private Color(int c) {
code = c;
}
public int getCode() {
return code;
}
how about a hashmap
HashMap<String,Integer> hm=new HashMap<String,Integer();
hm.put("treble-clef",0);
//rest
and get it by using this
int value=hm.get("treble-clef");