Unexpected Token - Java Enum - java

Is there any option in java to Create an enum with true and false like below,
public enum options {
true,
false,
both
}
Now getting unexpected token error as I am using true and false. thank you
Regards
haru

No. From JLS 8.9.1, an enum constant is defined in the syntax to be
EnumConstant:
{EnumConstantModifier} Identifier [( [ArgumentList] )] [ClassBody]
So it's an Identifier. And from JLS 3.8, and Identifier is defined to be
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
Hence, an identifier is any valid string of identifier characters (basically letters and numbers, but with Unicode support thrown in) that is not a keyword (like if) or the words true, false, or null.
Realistically, you should be capitalizing your enum names anyway, so it would look more like
public enum Options {
TRUE, FALSE, BOTH
}
which poses no issues as TRUE and FALSE aren't Boolean literals in Java.

The values of your enum should be formatted like constants; all-caps with underscores between words (if they are more than one word, which in your case, they are not). If you need to be able to convert them to/from strings that do not match the name and case of the enum constants, I would suggest adding a parameter with the string and methods to convert in each direction:
public enum Options {
TRUE("true"),
FALSE("false"),
BOTH("both");
private final String description;
private Options(final String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public static Options parse(String description) {
for (Options option : Options.values()) {
if (option.getDescription().equals(description)) {
return option;
}
}
throw new IllegalArgumentException("no such option: " + description);
}
}
If you call Options.parse("true") it will return Options.TRUE and if you call Options.TRUE.getDescription() it will return "true". If you call Options.parse("none") it will throw an IllegalArgumentException.

Related

Is there any method in ObjectMapper to match json string with Enum

I have an Enum
public enum status{
YES,
NO
}
the input from json string is "Yes" or "No", is there any method in ObjectMapper to match status.YES with "Yes", and status.NO with "No".
I don't want to change enum, because int my previous system, people use the enum all the time, I don't want cause problem for others
You can always redefine it like:
public enum Status {
YES("Yes"),
NO("No");
private final String status;
private Status(final String status) {
this.status = status;
}
public String value() {
return this.status;
}
}
And then use something like this: Status.YES.value();
You can use toString() method available in all Java enums:
http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html
and on returned String call compareToIgnoreCase method to compare it with input:
http://www.tutorialspoint.com/java/java_string_comparetoignorecase.htm
Or you can call toUpperCase on input String and then comapre them:
http://www.tutorialspoint.com/java/java_string_touppercase.htm
Finally, you can use toString mentioned earlier and put all letters except the first to lower case:
String YesString = enumWithYESValue.toString().substring(0, 1) + enumWithYESValue.toString().substring(1).toLowerCase();
Based on: How to capitalize the first letter of a String in Java?

Drools return list of rules

I'm new to drools and I succeded in creating a working application that uses the created rules. I have a simple class Message with two variables type and language.
public class Message {
private String type;
private String language;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
}
My rules are implemented as
rule "test_auto"
when
message:Message (( type == 'string1' ) && ( language == 'string2' ) )
then
...
end
If the user inserts some strange values for both type or language , I have a particular rule that returns an error. But on top of that I wanted to know if it is possible to return also the list of all the possible variables inserted in the rules: for example string1 and string2.
I guess you mean "string literals" and not variables?
There's a class for representing a rule; with classes for patterns and constraints. But these are "not stable", and it is generally not advisable to base an application on them.
If you have several rules catching some bad combination of Message.type and Message.language, you might consider inserting Facts according to
class BadMessage {
String type;
String language;
}
with all those "bad" combinations, and a single rule
rule "catch bad messages"
when
$m: Message'( $t: type, $l: language )
BadMessage( type == $t, language == $l )
then
// handle $m as a "bad" message
As an aside, note that you can write your pattern simply as
message: Message( type == "string1", language == "string2" )

What would be the best way to create association in a list (array) of arbitrary things?

I'm making a word-definition quiz app, and my list of words and their definitions is in JSON, structured like this:
"words": [
{
"word": "rescind",
"type": "verb",
"definition": "to take back, repeal as in a rule or policy"
},
{
"word": "curtail",
"type": "verb",
"definition": "to reduce or lessen"
},
etc, etc.
In the quiz, you're given one randomly picked word, and five definitions to choose from. Like a standardized multiple-choice test.
Now, a problem I'm starting to see is that I have words with very similar meanings. I currently have the 4 wrong definitions picked randomly from the list, but to avoid confusion, I want to avoid picking definitions that are similar to the correct choice.
How should I go about creating this "similarity" map? One solution I thought of would be this:
{
"word": "avid",
"type": "adjective",
"definition": "extremely excited about, enthusiastic about",
"similar to": [
"ardent",
"fervent"
]
},
But I realized this solution kinda sucks because I have to go to each other word and implement the same list, and it'll get real bulky to edit when I end up adding lots and lots of words.
So what do you guys think would be the best solution?
A simple first approach would be to create a Word class with fields.
Make sure you override equals() and hashCode() using the "word" field (I calle dit "value" to distinguish it from the class name) (see below):
public class Word {
private final String value;
private final String type;
private final String definition;
private final List<Word> synonymns = new ArrayList<Word>();
public Word(String value, String type, String definition) {
this.value = value;
this.type = type;
this.definition = definition;
}
// equals() and hashCode() based on the value field
#Override
public int hashCode() {
return value.hashCode();
}
#Override
public boolean equals(Object obj) {
return obj instanceof Word && ((Word)obj).value.equals(value);
}
public String getValue() {
return value;
}
public String getType() {
return type;
}
public String getDefinition() {
return definition;
}
public List<Word> getSynonymns() {
return synonymns;
}
}
Implementing equals() and hashCode() based on the value field means you can prevent duplicates by using a Set:
Set<Word> words = new HashSet<Word>(); // wont allow two Word objects with the same value
You can use the return value from Set.add(), which true if the set did not already contain the specified element, to check that the word being added is in fact unique:
Word word = new Word("duplicate", "adjective", "another copy");
if (!words.add(word)) {
// oops! set already contained that word
}
If you wanted to add special sauce, make the type an enum:
public enum PartOfSpeach {
NOUN,
VERB, // in USA "verb" includes all nouns, because any noun can be "verbed"
ADJECTIVE,
ADVERB
}
You may consider allowing words to belong to multiple types:
bark: verb: what dogs do
bark: noun: what covers a tree
In fact, you may consider having multiple meanings per Word:
public class Meaning {
PartOfSpeach p;
String definition;
List<Word> synonyms; // synonyms belong to a particular *meaning* of a Word.
}

take the value of enum and covert it to String

I should take from a variable enum its value and transform it to string.how can i do?
here it is the type enum:
public enum State{
b,c,p;
};
now i have to insert into an object String one value.
You might use enum.name orenum.toString to get the name of the enum constant, or enum.ordinal to get the ordinal position.
you can use name() or toString(), so :
State aState = State.c;
String strState = aState.name();
See here the official java reference for more information...
State.b.toString() will return "b". The same goes for the other ones.
Usually,
State state = ...;
String string = state.toString();
should work, but it is not recommended since someone might override toString for some other purpose.
Instead the method you are looking for is
String string = state.name();
As an aside, your enumerated stated should always be all in capitals, and they should have descriptive names. It's not a language rule, but a convention. For example enum State { ON, OFF, PAUSED; }.
I tend to do something more complicated, but I find that it's more flexible:
public enum MyEnumeration {
SOME_NAME("Some Name"),
OTHER_THING("Other Thing"),
...
MORE_VALUES("More Values"),
private final String displayName;
private MyEnumeration(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
This way, I use standard capitalization for my enums in code, but can have a more presentable name for them.
This trick can also be used to replace ordinal, by initializing a number, and then you don't need to worry about rearranging your enums.
Method #1: Using the built-in toString() and name() methods
If you want to print a String that is the same as the value of the State, then you can use the toString() method, or the name() method.
System.out.println(State.b); // Prints "b"
System.out.println(State.c); // Prints "c"
System.out.println(State.p); // Prints "p"
Method #2: Using a constructor to create a custom mapping
If you want to have a custom String associated with each of those states, you can use a constructor to associate a particular value with each enum value:
public enum State{
b("State B"), c("State C"), p("State P");
private String longName;
private State(String longName) {
this.longName = longName;
}
#Override
public String toString() {
return this.longName;
}
};
Of course, if you don't want to break the default toString() usage, you can create a different method called getFullName(), for example, to return the custom value.

Can I give an enum an attribute in VB.NET (like I can do in Java)?

In Java I can do something like this:
enum Country {
IRELAND("Europe"),
FRANCE("Europe"),
NIGERIA("Africa"),
THAILAND("Asia");
private String continent;
Country(String continent) {
this.continent = continent;
}
public String getContinent() {
return continent;
}
}
which allows me to do something like:
Country country1 = getCountryFromSomewhere();
Country country2 = Country.FRANCE;
System.out.print("country1 is in " + country1.getContinent());
System.out.print("country2 is in " + country2.getContinent());
Is it possible to do the same thing in VB.NET i.e. add the continent attribute to the country enum?
(Apologies for using C# throughout - I believe the concepts are more about .NET than the language you happen to use; hopefully you're better at reading C# than I am at writing VB.)
Not directly - enums in .NET are just integer types with names for some of the values.
The closest you can come in .NET is to create a type with a fixed set of values. For example, in your case:
public sealed class Country
{
public static readonly Country Ireland = new Country("Europe");
public static readonly Country France = new Country("Europe");
public static readonly Country Nigeria = new Country("Africa");
public static readonly Country Thailand = new Country("Asia");
private readonly string continent;
public string Continent { get { return continent; } }
private Country(string continent)
{
this.continent = continent;
}
}
(I assume the VB.NET would be very similar.)
Note that this doesn't let you switch on the enum values.
If you want polymorphism, you can create nested subclasses which can still call the private constructor, which prevents any other subclasses being created.
One alternative to this is to use attributes on normal enums:
[AttributeUsageAttribute(AttributeTargets.Field)]
public class ContinentAttribute : Attribute
{
// etc
}
public enum Country
{
[Continent("Europe")] Ireland = 1,
[Continent("Europe")] France = 2,
...
}
You'd then need to use reflection to get at the ContinentAttribute and retrieve the string.
Note that here there isn't really a fixed set of values - you could write:
Country country = (Country) 15;
At that point you can't get the continent for it, and if you pass it to any methods which expect it to be a real country, you've got problems. That isn't the case with the earlier solution, where you really are restricted to those few values (and null).
Here is the code:
Imports System.ComponentModel
Imports System.Reflection
Public Enum enumOrderStatus
<Description("None")>
None
<Description("Sent")>
Sent
<Description("Accepted")>
Accepted
<Description("Cancelled")>
Cancelled
<Description("Declined")>
Declined
End Enum
Public Function GetEnumDescription(ByVal EnumConstant As [Enum]) As String
Dim fi As FieldInfo = EnumConstant.GetType().GetField(EnumConstant.ToString())
Dim aattr() As DescriptionAttribute = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
If aattr.Length > 0 Then
Return aattr(0).Description
Else
Return EnumConstant.ToString()
End If
End Function
I used this solution instead:
Declare enum:
Private Enum Country
IRELAND
FRANCE
THAILAND
End Enum
Declare and initialise Dictionary (aka a map):
Dim countryContinentMap As IDictionary(Of Country, String) = New Dictionary(Of Country, String)
countryContinentMap.add(Country.IRELAND, "Europe")
countryContinentMap.add(Country.FRANCE, "Europe")
countryContinentMap.add(Country.THAILAND, "Asia")
which allows me to get the continent like this:
Dim franceContinent As String = countryContinentMap(Country.FRANCE)
Here is how I solved this in my application. Still looking for something even easier.
What do you think about it?
Public Sub Init()
Dim values() As Integer = CType([Enum].GetValues(GetType(MyEnum)), Integer())
For i As Integer = 0 To values.Count - 1
Me.contextMenuInGUI.Items.Add(Me.GetEnumDescription(i))
Next
End Sub
Private Function GetEnumDescription(ByVal i As Integer) As String
Select Case i
Case MyEnum.Comment
Return "Description for Comment"
Case MyEnum.SomeEnumValueInCamelCase
Return "Value without camel case (€)(%)(#)"
End Select
Return "Add a case in Class:GetEnumDescription"
End Function
Create an extension method for your Enum
Usage example:
dim description = TableTag.Important.GetDescription()
Definition example:
Imports System.ComponentModel
Imports System.Reflection
Imports System.Runtime.CompilerServices
Namespace Foo
Public Enum TableTag
<Description("Identifies tables that should be availible for writing as table or view to the model database")>
Important
<Description("Example for a table group that helps to select disctinct tables")>
CustomGroup
End Enum
Public Module TableTagExtensions
<Extension>
Public Function GetDescription(enumValue As TableTag) As String
Dim fieldInfo As FieldInfo = enumValue.GetType().GetField(enumValue.ToString())
Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
If attributes.Length > 0 Then
Return attributes(0).Description
Else
Return enumValue.ToString()
End If
End Function
End Module
End Namespace

Categories

Resources