I am trying to get input validation by comparing the result of a string (from Scanner) to an Enum of potential values.
The Enum contains the name of all Countries in the world, the user is asked to enter a country name -- the input should only be allowed IF the input value is present in the Enum -- is there a way to do this?
Thanks!
The most efficient way is to try to get Enum by name and catch the exception, using Enum.valueOf(String) method:
try {
CountryEnum country = CountryEnum.valueOf( "user-input" );
} catch ( IllegalArgumentException e ) {
System.err.println( "No such country" );
}
Another way without catching exceptions is to compare user input to each of enum values:
String userInput = ...;
boolean countryExists = false;
for( CountryEnum country : CountryEnum.values() ) {
if( userInput.equalsIgnoreCase( country.name() ) ) {
countryExists = true;
break;
}
}
if( !countryExists ) {
System.err.println( "No such country" );
// exit program here or throw some exception
}
Use Enum.valueOf("string") != null if the string value exists as a type enum
Find more reference here - http://www.tutorialspoint.com/java/lang/enum_valueof.htm
You can equip the Enum with a method getByName(String name) that returns null if the Enum holds no corresponding value for the given name:
public enum Country {
AFGHANISTAN,
ALBANIA,
ALGERIA,
...
public static Country getByName(String name) {
try {
return valueOf(name.toUpperCase());
} catch (IllegalArgumentException e) {
return null;
}
}
}
Now when a user enters 'Neverland', obviously getByName('Neverland') returns null, which you can test for. Instead of null you could also include a catch-all value in your list and return that, e.g. TERRAINCOGNITA.
Following should work
public class EnumTest {
enum Country{IND, AUS, USA;
static boolean exists(String key) {
Country[] countryArr = values();
boolean found = false;
for(Country country : countryArr) {
if(country.toString().equals(key)) {
found = true;
break;
}
}
return found;
}
};
public static void main(String[] args) {
System.out.println("Started");
Scanner scan = new Scanner(System.in);
System.out.println(Country.exists(scan.nextLine()));
scan.close();
}
}
Of course you can implement a more efficient search by using a Set to store values.
Enum.valueOf can not be used as it throws following exception when passed value does not match to any enum constant.
java.lang.IllegalArgumentException: No enum constant
public enum RegisterType {GUIDE, VISITOR, TICKET, RECEPTIONIEST;}
RegisterType type = RegisterType.valueOf(input.next());
Related
I have an enum class with values:
enum carBrand{BMW,HONDA,MERC,AUDI};
And there's an array called Sales with Array values:
sales[] = {CHEVVY, BMW , MERC, AUDI};
So how could I check that the sales[] has all the values of enum carBrand?
I'm trying to put it in a for loop as:
for(int i = 0; i<sales.length;i++){
if(carBrand.sales == sales[i]){
return true;
}
return false;
}
Add carBrand values to list
loop sales, remove the carBrand from the list
check if list is empty, if so they have all the values
Note: Class names should be names in PascalCase (CarBrand, Sales)
I would, personally, suggest using a list object rather than an Array where you are using such, however, this should work.
public static boolean checkArray(carBrand[] array) {
for (carBrand c : carBrand.values()) {
boolean found = false;
for (carBrand a : array) {
if (a == c) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
where the "array" parameter would be invoked as the sales object in your code.
This code will return false if not every enum value exists within your array.
Off-topic:
Things like this are actually all over the internet - here, google, even Bing (as garbo as Bing is), so searching before requesting help, probably a viable choice
public class Enumeration {
enum carBrand{BMW,HONDA,MERC,AUDI};
public static void main(String[] args) {
String sales[] = {"CHEVVY", "BMW" , "MERC", "AUDI"};
for(carBrand brand:carBrand.values()) {
boolean bran=false;
for(int i=0;i<sales.length;i++) {
if(brand.toString()==sales[i]) {
bran=true;
break;
}
}
if(!bran==true) {
System.out.println("Sales doesn't have " +brand);
}
}
}
}
I have the following code :
class MyClass {
private Value value;
public enum Value {
INSERT_ONLY("INSERT_ONLY"), UPDATE_ONLY("UPDATE_ONLY"), UPSERT("UPSERT") ;
private final String val ;
private Value(final String v) {val = v ;}
public String toString() {return val ;}
public String getVal() {
return val;
}
} ;
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
}
public class one {
public static void main(String[] args) {
MyClass obj = new MyClass() ;
obj.setValue(MyClass.Value.INSERT_ONLY) ;
String s = obj.getValue().toString() ;
String s1 = MyClass.Value.INSERT_ONLY.toString() ;
switch(s) {
case "INSERT_ONLY" : System.out.println("INSERT_ONLY") ;
break ;
case "s2" : System.out.println("s2") ;
break ;
}
}
}
This code works. But what I want is that in switch-case I use the strings as defined in the enum Value. If I use s1 in case, it generates an error. What is the way out?
Enums have a method .name() that returns the enum as a String. All your "values" are equivalent to this - just switch on that.
You can delete the value field, the constructor and getter and call name() where you are currently calling getValue().
Further, the default implementation of toString() returns name() so you can delete your toString() method without having any effect.
Finally, you can switch on the enum itself.
you string in the enum is actually the same as the enumertor constants... so it is a little redundant and completely unnescessary...
try this:
enum Value {
INSERT_ONLY, UPDATE_ONLY, UPSERT;
}
public static void main(String[] args) {
Week obj = new Week() ;
Value s = obj.getValue( ) ;
switch(s) {
case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
break ;
case UPDATE_ONLY : System.out.println("UPDATE_ONLY") ;
break ;
}
}
}
You could try it this way:
MyClass.Value value = obj.getValue() ;
switch(value) {
case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
break ;
case UPSERT : System.out.println("Upsert") ;
break ;
case UPDATE_ONLY : System.out.println("Update only") ;
break ;
}
Basically, the switch-statement uses the enum-names. So there is no need to apply the toString()-method on the Value returned by obj.getValue().
If you would like to know why switch will not work in combination with strings, please have a look here.
One more suggestion: add also the default-branch to the switch-statement.
If I understand correctly, you're trying to look up an enum constant by an unknown string s. The reason your case expression can't be s1 is because it must be a compile-time constant, which s1 is not. Since your example seems to be mostly theoretical, I'll suggest a few options and you can pick the most appropriate for your actual case:
Assuming the enum names are the same as their values (in which case you can scrap the field entirely) and you're just trying to look up an enum by its name, just do this:
MyClass.Value v = MyClass.Value.valueOf(s);
This will throw an IllegalArgumentException if no mapping is found for s1.
Still assuming the names are the same, but you do need an actual switch with some additional cases and custom logic:
try {
MyClass.Value v = MyClass.Value.valueOf(s);
switch (v) {
case INSERT_ONLY : System.out.println("INSERT_ONLY") ;
break ;
}
} catch (IllegalArgumentException e) {
switch (s)
case "s2" : System.out.println("s2") ;
break ;
}
}
If the names are not actually the same, you can add a static map of constants inside the enum class, to simulate valueOf():
public enum Value {
ONLY_INSERT("ONLY_INSE"), ONLY_UPDATE("UPDATE_ONLY"), UPSERT("UPSERT") ;
private static final Map<String, Value> byName = new HashMap<>();
static {
for (Value v : values()) {
byName.put(v.getVal(), v);
}
}
public static Value byName(String name) {
Value result = byName.get(name);
if (result == null) {
throw new IllegalArgumentException("Invalid name" + name);
}
return result;
}
private final String val ;
private Value(final String v) {val = v ;}
public String toString() {return val ;}
public String getVal() {
return val;
}
} ;
Now you can do the same as the previous solutions, using MyClass.Value.byName().
I'm looping through an enum to find a certain value. If it finds it it continues the program. Else, it closes the program. My current algorithm is checking if all of the values are equal instead of continuing when one is equal. How do I make it continue if it finds one equal value.
public enum stuff{
//
apple("apple.png"),
banana("banana.png"),
spinach("spinach.png");
//
//Variables
private String Path;
//Constructor
Enemies (String path) {
Path = path;
}
public String getPath() {
return Path;
}
}
Actual loading done in another class
String stuffType = banana;
for (stuff s : stuff.values()) {
if(stuffType != s.name()){ //checks if any are a banana
System.exit(0);
}
}
You could use a loop, or you could use the valueOf method, which looks up an enum constant by name already, and throws an IllegalArgumentException if there is no enum constant with that name.
String stuffType = "banana";
try {
stuff.valueOf(stuffType);
} catch(IllegalArgumentException e) {
// stuff doesn't contain an enum constant with a name that matches the value of stuffType
System.exit(0);
}
I am new to Java,
Here is my code,
if( a.name == b.name
&& a.displayname == b.displayname
&& a.linkname == b.linkname
......... )
return true;
else
return false;
I will call this method and have to check that all properties of objects 'a' and 'b'.
Each object will have more than 20 properties. So, it is will be tidy if i use if case for each property.
An exception is throwed if the return is false and I have to report which property fails.
Is there any easy method to find where the condition fails within the if case.
Pls help. Ask if you are not clear about the question.
The question is, would you like to continue checking if one of the conditions fails?
You could do something like comparator where you have interface:
public interface IComparator {
boolean compare(YourObject o1, YourObject o2);
String getComparatorName();
}
Next you create set of implementations of that interface:
NameComparator implements IComparator {
private name="Name Comparator";
#Override
public boolean compare(YourObject o1, YourObjecto2) {
return o1.getName().equals(o2.getName());
}
#Override
public String getComparatorName() {
return name;
}
}
Next you store set of these comparators in arrayList and you iterate through them and record which one fails by adding them to some other collection.. Hope that helps!
For instance you create array:
IComparator[] comparators = new IComparator[]{ new NameComparator, new DisplayNameComparator};
List<IComparator> failedComparationOperations = new ArrayList<IComparator>();
for(IComparator currentComparator : comparators) {
if(!currentComparator.compare(o1, o2)) {
failedComparationOperations.add(currentComparator);
}
}
for(IComparator currentComparator: failedComparationOperations)
{
System.out.println("Failed Comparation at: "+currentComparator.getComparatorName());
}
You may use reflection: browse what fields are defined, and check each of them using method equals. Print error message if they're not equal, give summary at the end.
boolean equals = true;
Field[] fields = a.getClass().getDeclaredFields();
for (Field f: fields){
f.setAccessible(true);
try {
if (!f.get(a).equals(f.get(b))){
System.out.println(f.getName() + ": " + f.get(a) + "!="+ f.get(b));
equals = false;
};
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("equals?: " + equals);
If you need to know which of the conditions has failed you should check each of the conditions independently.
It might be a little overkill if you are dealing with this single requirement, but what about the Strategy Design Pattern?
http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
It should be an interesting option if you have other business rules that you can combine with this check.
If a and b are instances of the same class, let's assume A, and the fields are visible, then you can use reflections:
for (Field f : A.class.getFields()) {
try {
if (!f.get(a).equals(f.get(b))) {
throw new RuntimeException("Field " + f.getName() + " is different.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Without reflection you can't get maximum conciseness, but the followincg can help you to some extent. Make this kind of class:
class NamedEquals {
final String name;
final Object left, right;
NamedCondition(String name, Object left, Object right) { ...assign them... }
boolean areEqual() { return left.equals(right); }
}
Then make a List<NamedEquals>:
List<NamedEquals> conds = Arrays.asList(
new NamedEquals("name", left.name, right.name),
new NamedEquals("displayname", left. displayname, right.displayname),
...
);
And you can find if some of them fail:
for (NamedEquals eq : conds)
if (!eq.areEqual()) throw new ValidationException(eq.name);
Using a factory method can shorten the construction code:
static NamedEquals eq(String name, Object left, Object right) {
return new NamedEquals(name, left, right);
}
With that you can have
List<NamedEquals> conds = Arrays.asList(
eq("name", left.name, right.name),
eq("displayname", left. displayname, right.displayname),
...
);
How about?
// Adapted from your example:
if(!equalTo(a.name, b.name))
fail("name");
if(!equalTo(a.displayname, b.displayname))
fail("displayname");
... etc ...
...
// Allow for null values.
public boolean equalTo(Object a, Object b) {
return a != null ? a.equals(b) : b == null;
}
public void fail(String which) throws SomeException {
throw new SomeException("Failed on '"+which+"'!");
}
Another possible might be to turn each object into a Map<String,?>, perhaps by adding a Map<String,?> toMap() method to the value object, and implementing this by constructing a new map and dumping the value's fields into it. Then you can get the maps and do equals() on them.
I need to search an object array for a Name and then print out all info corresponding to that name.
I have
public class AccessFriendlyFile {
private Friendlies[] fr = new Friendlies[100];
private int size = 0;
public AccessFriendlyFile (){
try {
Scanner scFile = new Scanner(new File("Friends.txt"));
String line, name, surname, cell, mail, landline;
while (scFile.hasNext()){
line = scFile.nextLine();
Scanner sc = new Scanner(line).useDelimiter("#");
name = sc.next();
surname = sc.next();
cell = sc.next();
if (sc.hasNext()){
mail = sc.next();
landline= sc.next();
fr[size] = new ExtendFriendlies(name, surname, cell, mail, landline);
}
else {
fr[size]= new Friendlies(name, surname, cell);
}
size++;
sc.close();
}
}catch (FileNotFoundException ex){
System.out.println("File not found");
}
How do I code a method that will search "fr" for a name and print out all corresponding info?
Many Thanks
Jesse
Edit:
Here is my Search method, that is currently not working.
public int Search(String name) {
int loop = 0;
int pos = -1;
boolean found = false;
while (found == false) {
if (fr[loop] == name) {
found = true;
pos = loop;
} else {
loop++;
}
}
return pos;
}
Incomparable types error on the if statement.
In your Friendlies class, have a method called getName() that will return the name of that Friendly. Iterate through the fr until you find the matching name. Once you've found that name, use similar get methods to print out all the information you want for the matching Friendly you just found.
I would suggest that you rename your variables here. The Friendlies class stores, I think, a single contact, a Friend. The list of Friend objects is an array that you might beter name friendList or even friendlies. I would also encourage you to not use size as a counter variable. Size is how many friends you have, and you can iterate through them using i, or friendCounter, or use a for each loop as I demonstrate below,
public Friendlies find(String name) {
for(Friendlies friend : fr) {
if(friend.getName().equalsIgnoreCase(name))
return fiend;
}
return null;
}
//now to print the info you can do this:
Friendlies findJoe = find("Joe");
if(findJoe==null)
System.out.println("You have no friends namd Joe.");
else
System.out.println(findJoe);
My code assumes that you implement toString() in Friendlies. If you use netbeans, you can auto-generate this code and then tweak it to get the format you want. (Just right-click where you want to write the method and choose insert code)
This should work:
public List<Friendlies> search(String name) {
List<Friendlies> list = new ArrayList<Friendlies>();
for(Friendlies friendlies : fr) {
if(friendlies.getName().equals(name)) {
list.add(friendlies);
}
}
return list;
}
Then, with the returned list, implement a nice display of the data :)
Assuming the AccessFriendlyFile loads the data into your array, you can use a for each loop, if you want to retieve all the matching names :
List<Friendlies> getByName(String searched){
List<Friendlies> result = new Arraylist<Friendlies>();
for (Friendlies currentFriendly : fr){
if (searched.equalsIgnoreCase(currentFriendly.getName()){
result.add(currentFriendly);
}
}
return result;
}
for only the first one :
Friendlies getByName(String searched){
for (Friendlies currentFriendly : fr){
if (searched.equalsIgnoreCase(currentFriendly.getName()){
return currentFriendly;
}
}
return null;
}
You should use lists instead of fixed arrays. If the files contains more than 100 records you'll get an indexoutofbounds exception.