问题
Extending this question, I have accepted an answer which says use lookup table or hashmap for this case as it would be a better construct to handle multiple conditions.
Current construct.
Class to store messages.
public class ProgressMessages
{
public static String msg1="Welcome here .....";
.
.
.
//around 100 more similar static variables.
}
Condition and Display the proper message from the above class.
int x=calculatedVal1(m,n);
int y=calculatedVal2(o,q);
SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d=new Date();
String s=formater.format(d);
try {
long d1 = formater.parse("2013-01-10 13:53:01").getTime();
long d2=formater.parse(s).getTime();
totaldays=Math.abs((d1-d2)/(1000*60*60*24));
} catch (ParseException e) {
e.printStackTrace();
}
if(totaldays<7&&x<20)
{
System.out.println("my message...1"+ProgressMessages.msg1);
}
else if(totaldays<7&&x>10&&y<20)
{
System.out.println("my message...2"+ProgressMessages.msg2);
}
....
//obvioulsy 100 more else-if's to display 100 messages.
I actually would like to know how would a look-up table help in this case?
How should it be implemented in java Hashmap/Hashtable etc, What would be advantageous how?
----Edit---
I am going by @assylias anwer as it is more clean to apply . But If I use Enums then I have got a fix.
To describe the big picture...
i.e. List of messages is like...
1) "Welcome," + nameOfUser+"your success rate is"+ succssRate +"%"+ earlier it was +earlier +"%".
2) "Oh yes.."+ succssRate +"%"+ improved from +earlier +"%".
3.) "Now you should focus on "+exerCiseName.
How could I do this using Enumeration as it has fixed String data. Could I make different constructors? How any example with the edit code to assylas answer?
回答1:
I would use a
Map<Criteria, Message> lookupTable;
where Criteria
is a class you write (and override equals()
and hashCode()
), representing the criteria to choose a message.
Message
is also a class you write, which encapsulates the actual message String
but also provides you some functionality to set the variables.
With this solution you have to initialize the map once at the beginning of your program and can always use it like this:
Criteria criteria = ... // gather your criteria somehow
Message msg = lookupTable.getMessage(criteria);
// use your variable setting methods here
String message = msg.toString();
回答2:
You could use an enum, assuming the list of messages is known at compile time. The advantages are that each message is now responsible for holding its condition, and the calling code will be much simpler.
public enum Message {
MESSAGE1("Welcome") {
@Override
boolean isApplicable(long totalDays, int x, int y) {
return totalDays < 7 && x < 20;
}
},
MESSAGE2("Bye bye") {
@Override
boolean isApplicable(long totalDays, int x, int y) {
return totalDays < 7 && x > 10 && y < 20;
}
};
private String msg;
Message(String msg) {
this.msg = msg;
}
abstract boolean isApplicable(long totalDays, int x, int y);
public static String lookupMessage(long totalDays, int x, int y) {
for (Message m : Message.values()) {
if (m.isApplicable(totalDays, x, y)) {
return m.msg;
}
}
throw new IllegalArgumentException();
}
}
Now in your calling code, no more if / else if, just one line of code:
System.out.println(Message.lookupMessage(1, 2, 3));
Note 1: This is not as efficient as using a Map as the lookup is an O(n) operation, but because n is 100 or so it should not be a significant performance penalty. And it is more readable and maintainable than the solution proposed in the other answer.
Note 2: You could even put the conditions / messages in a flat file, read the file at runtime and use a scripting engine to eval each condition at runtime. It would be slightly slower (but we are talking about sub-milliseconds here) but would remove all the clutter from your code and put it in a configuration file.
回答3:
If you have so many conditions, you cant avoid putting those conditions some where in the code. The advantages of using lookup table is 1)Easy to implement. 2)Flexible.If you want to change the value of some message in future, you can go to looktable class and change.
来源:https://stackoverflow.com/questions/14252822/java-create-a-lookup-table-using-hashmap-or-some-other-java-collection