I need to read a flag to validate if I'll send or not an email, this flag is on a LinkedHashMap, so I'm trying to go over it looking for an ID, then I'll have to ask if is true or false, and I'm trying this:
while(iterator.hasNext()){
LinkedHashMap<String, Object> fileMap = (LinkedHashMap<String, Object>) iterator.next();
userid = (Long)fileMap.get("USERID");
file.findAllFiles(userid);
if(file.findAllFiles(userid).contains(haveFiles = true)){
//send email
}else{
//do something
}
}
Is it correct?
I think your if expression has a logical error.
haveFiles = true
will always return true, reducing your expression to :
file.findAllFiles(userid).contains(true)
since (haveFiles = true) assigns the value true to the variable haveFiles.
You should rather be doing something on the following lines :
Map<Flag, Boolean> keyValueMap = file.findAllFiles(userid)
if(keyValueMap.contains(Flag.HAVE_FILES) == true){
//send email
}else{
//do something
}
..asuming you the file.findAllFiles() returns a map object with flags and their boolean status and Flag is an enum containing all the supported flags.
The expression
(keyValueMap.contains(Flag.HAVE_FILES) == true)
will evaluate to true only when keyValueMap contains an entry for Flag.HAVE_FILES and the value is true.
Assuming it works up to the point of:
if(file.findAllFiles(userid).contains(haveFiles = true))
Then I think the issue is in that condition itself. What you have written is roughly equivalent of writing
??? haveFiles = true;
if(file.findAllFiles(userid).contains(haveFiles))
(where ??? can be either Object, Boolean or boolean, don't know from your code snapshot)
I bet what you might want to do is something like
Boolean haveFiles = file.findAllFiles(userid).get("haveFiles");
if (Boolean.TRUE.equals(haveFiles) {
What you have done calls the contains method which receives any Object and returns true if that object is among the values of the map. You probably don't want that, I guess what you want to do is to retrieve the value associated to the "haveFiles" key into the map, for that you have to use the get method.
PS: Also, if file.findAllFiles(userid) method is truly calling some DB stuff you might want to invoke it only once (the first time looks totally unnecesary to me).
Related
I am supposed to implement two functions that I already created (named isTargetWithinRange (what it does: given a target, this says whether a target is within range) and isTargetVisited (which checks that the target wasn't already captured)).
In this part, I am supposed to get the index of an unvisited target within the "range" (maximum distance to my target) of my current location. To do this, I am trying to create a for loop that contains an if-statement that calls my two variables.
The trouble that I am having is that I do not know how to call functions within the if-statement (that is within a for loop). I am trying to say within the if-statement that if isTargetWithinRange returns true or if isTargetVisited returns false, then the result is -1 (which in this case represents a target that is not yet captured).
if (isTargetWithinRange(i) return true || isTargetVisited(i) return false)
return -1;
}
}
I know that this question is probably incredibly confusing...but I really need help. I will try and clarify/define anything I can to get some help...
Something like this should do the job
if (isTargetWithinRange(i) || !isTargetVisited(i)) {
return -1;
}
You need to separate the method that returns true or false ( a predicate) from the action you want to take depending on the result. For example:
if(doIReturnTrue()) { // if true do something } .
The if statement will receive the result from the function, so you don't need
isTargetWithinRange(i) return true
Instead just pass the result of the method return into the if statement
if(isTargetWithinRange(i)){ // do if true etc }
To test a false result negate the return value using the logical not ! operator
if(!isTargetVisited(i)){ // do if true }
In the above when isTargetVisited returns false apply the 'logical not' to change this to true
I see that you might be new in Java. A function will return a value, in your case it is probably a boolean. Therefore you can use the following to achieve your result:
if (isTargetWithinRange(i) == true || isTargetVisited(i) == false) {
return -1;
}
Since the function will return a value, the == will check if the returned value is equal to what you want it to be.
I have just wrote a code to cach a table in the memory (simple java hashmap). Now one of the code that i am trying to replace is the find the objects based on criteria. it receives multiple field parameters and if those fields are not empty and not null, they were being added as part of hibernate query criteria.
To replace this, what i am thinking to do is
For each valid param (not null and no empty) I will create a HashSet which will satisfy this criteria.
Once i am done making hashsets for all valid criteria, I will call Set.retainAll(second_set) on all sets. So that at the end, I will have only that set which is intersection of all valid criteria.
Does it sound like the best approach or is there any better way to implement this ?
EDIT
Though, My original post is still valid and I am looking for that answer. I ended up implementing it in the following way. The reason is that it was kind a cumbersome with sets since after creating all sets, I had to first figure out which set is non empty so that the retainAll could be called. it was resulting in lots of if-else statements. My current implementation is like this
private List<MyObj> getCachedObjs(Long criteria1, String criteria2, String criteria3) {
List<MyObj> results = new ArrayList<>();
int totalActiveFilters = 0;
if (criteria1 != null){
totalActiveFilters++;
}
if (!StringUtil.isBlank(criteria2)){
totalActiveFilters++;
}
if (!StringUtil.isBlank(criteria3)){
totalActiveFilters++;
}
for (Map.Entry<Long, MyObj> objEntry : objCache.entrySet()){
MyObj obj = objEntry.getValue();
int matchedFilters = 0;
if (criteria1 != null) {
if (obj.getCriteria1().equals(criteria1)) {
matchedFilters++;
}
}
if (!StringUtil.isBlank(criteria2)){
if (obj.getCriteria2().equals(criteria2)){
matchedFilters++;
}
}
if (!StringUtil.isBlank(criteria3)){
if (game.getCriteria3().equals(criteria3)){
matchedFilters++;
}
}
if (matchedFilters == totalActiveFilters){
results.add(obj);
}
}
return results;
}
I'm sort of confused, I guess this question is just a matter of preference, I just want to understand the difference of the following code.
if (IsRegistered() == true) ...
public boolean IsRegistered()
{
private boolean status = false;
// blah blah code here
return status;
}
vs
isRegistered = IsRegistered();
if (isRegistered)
I know both would work, I'm not being pedantic but I just want to understand so I would know my way around.
if (isRegistered() == true) ...
This is verbose since you know if it returns true it will do it, if not, it wont. So its the same as doing:
if (isRegistered()) ...
What it does, its just getting the returning boolean value from the method and checking the condition in the if statement.
Now if you wanted to check the boolean value again, you would need to re-call the method (which may have to do something complex to return that value), BUT if you assign it to a variable first and then check the condition, like this:
boolean isRegistered = isRegistered();
if (isRegistered)...
Later on the code you can just do it again without calling that method again.
if (isRegistered)... // n lines later.
hence, avoiding executing the process again.
At the end of the day, it pretty much depends on what you need to do.
When you invoke a method which has a non-void return type, the method itself resolves to a value the same way that using a variable does. You can either use that value directly or assign it to a variable and use that.
Just use:
if ( IsRegistered() )
It's the most readable code. Having a variable to "unbox" the method will not do any good; the compiler picks it up and replaces it into the control code itself in an internal optimization pass.
Also, the performance of your IsRegistered() method, when the self-optimization of machines is put aside, depends on how your "my code here" works:
source : {
private boolean status = false;
// blah blah code here
return status;
}
optimization-passed : {
return false; // When internal code does not modify "status"
preturn _status; // When internal code modifies "status"
}
I have created a method that uses an iterator that iterates through a map and for each pair it evaluates a statement with many OR conditions. If the condition is true, it adds the object of the pair (a Notification object) in a list (anomalies). However, at compilation time, the compiler gives a NullPointerException exception at this method. Based on my investigation, it seems that there is a problem in the if statement, but I can't see why. Can anyone give me an help in this? Thanks!
public List<Notification> getAnomalies(NotificationSearchCriteria notificationSearchCriteria) {
Map<String,Notification> messageList = new HashMap<String,Notification>();
List<Notification> anomalies = new ArrayList<Notification>();
Iterator iterator = messageList.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry pairs = (Map.Entry)iterator.next();
Notification message = (Notification) pairs.getValue();
if(message.getDescription().equals(notificationSearchCriteria.getDescription())||message.getSubjectName().equals(notificationSearchCriteria.getSubjectName())||message.getNotificationSubject().toString().equals(notificationSearchCriteria.getNotificationSubject().toString())||message.getNotificationType().toString().equals(notificationSearchCriteria.getNotificationType().toString())){
anomalies.add(message);
}
}
}
return anomalies;
}
This is most likely caused by one of the methods on message returning null. For example, if message.getDescription() returns null, then message.getDescription().equals(<something>) will throw a NullPointerException, since you can't call additional methods on a null object.
There are several ways to fix this. First off, I recommend inspecting your objects to see which can return a null value and add the appropriate handling code.
More generally, I always recommend calling equals on the variable you know not to be null to avoid these problems. For example
if ("accept".equals(command)) {
// do something
}
is generally better than
if (command.equals("accept")) {
// do something
}
because the second might through an NPE, while the first never will.
I would refactor the message-matching code into the NotificationSearchCriteria class. The if would end up being "if (notificationSearchCriteria.matches(message))". From the names, I am guessing that is NotificationSearchCriteria's only usage; in that sense, it would not increase coupling.
The check-for-null would be performed during NotificationSearchCriteria construction; which would ensure that all fields were non-null. In the matching code, within that class, things would look like:
boolean matches(Notification message) {
if (description.equals(message.getDescription()) || // LHS guaranteed non-null
foo.equals(message.getFoo()) ||
bar.equals(message.getBar()) || // ...
) { return true; }
}
The best way to code is to do null check.
Ideally I would have code like this :
while (iterator.hasNext()) {
Map.Entry pairs = (Map.Entry)iterator.next();
Notification message = (Notification) pairs.getValue();
if(null!=message && null!=message.getDescription() &&
null!=notificationSearchCriteria.getDescription() )
{
//Do your comparioson
}else{
//Handle the NullPointerException error the way you want
}
}
I'm writing an Android app for work that shows the status of our phone lines, but thats neither here nor there.
I make a call to one of our servers and get returned JSON text of the status. I then parse this putting each line into a SortedMap (TreeMap) with the Key being the name of the line and my own class as the value (which holds status and other details).
This all works fine.
When the app runs it should then show each line and the info I have retrieved, but nothing gets updated.
The JSON is returned and added to the Map correctly.
This is a snapshot of the code that isn't working. I simply iterate through the map and depending on the value of key update the relevant TextView. The problem I am having is that when it gets to the IF statement that matches it never runs that code. It skips it as if values don't match.
I can't see any errors. Is this the only way to do this as I know you can't use Switch..Case etc?
Can anyone see my error? I've been coding on Android for 1 week now so its probably a newbie error!!
Thanks
Neil
Iterator iterator = mapLines.entrySet().iterator();
while(iterator.hasNext())
{
// key=value separator this by Map.Entry to get key and value
Map.Entry<String, Status> mapEntry = (Map.Entry<String, Status>)iterator.next();
// getKey is used to get key of Map
String key = (String)mapEntry.getKey();
// getValue is used to get value of key in Map
Status value = (Status)mapEntry.getValue();
if(key == "Ski")
{
TextView tvStatus = (TextView)findViewById(R.id.SkiStatus);
tvStatus.setText(value.Status);
}
else if(key == "Cruise")
{
TextView tvStatus = (TextView)findViewById(R.id.CruiseStatus);
tvStatus.setText(value.Status);
}
else if(key == "Villas")
{
TextView tvStatus = (TextView)findViewById(R.id.VillasStatus);
tvStatus.setText(value.Status);
}
}
You must use equals() to compare String objects in Java. Otherwise you just compare if the two objects are the same instance of the String class and don't compare their actual content:
if (key.equals("Ski")) {
...
}
Or, to avoid a NullPointerException if key might be null:
if ("Ski".equals(key)) {
...
}
I prefer to use maps in this case because they eliminate the need for duplicated code and long if else constructs. I don't know where in your code this snippet occurs so this may not apply in your case but just to mention it.
Use a Map to get the correct resource for your String and set the status.
The code would look something like this:
First initialize the map:
Map<String, Integer> textViews = new HashMap<String, Integer>();
textViews.put("Ski", R.id.Ski);
textViews.put("Cruise", R.id.Cruise);
textViews.put("Villas", R.id.Villas);
Then retrieve the correct id and set the text:
((TextView) findViewById(textViews.get(key))).setText(status);
This will reduce the big if else construct a lot and adding a textview will be as easy as changing the map.
checking key with the string literal "Ski", you can use like below . This will prevent nullpointer exception.
if ("Ski".equals(key))
{
...
}