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);
}
Related
I have looked through other questions but cant seem to find the answer I am looking for.
I am having trouble figuring out how to create a loop that adds a class object to an ArrayList only if it its name is not used in the list already.
This is the class I have.
package myPackage;
public class Cube {
private int length;
private String name;
public Cube(int initLength, String initName) {
this.length = initLength;
this.name = initName;
}
I would like to create new cubes and add them to a list. Here is the code I am trying to do this with.
In the while loop I can't figure out how to determine if the name has been used or not
package myPackage;
import java.util.ArrayList;
import java.util.Scanner;
public class PartFive {
public static void main(String[] args) {
ArrayList<Cube> cubelist = new ArrayList<>();
Cube oshea = new Cube (13, "oshea");
Cube mike = new Cube (7, "tony");
cubelist.add(oshea);
cubelist.add(mike);
Scanner reader = new Scanner(System.in);
while (true) {
System.out.println("enter cube name (blank quits): ");
String name = reader.nextLine();
if (name.equals("")){
break;
}
System.out.println("enter side length: ");
int length = Integer.valueOf(reader.nextLine());
Cube newcube = new Cube(length, name);
if(cubelist.contains(newcube.name)) {
// dont add to list
}
else {
cubelist.add(newcube);
}
}
reader.close();
System.out.println(cubelist);
}
}
Any constructive criticisms and suggestions are welcomed.
Replace
if(cubelist.contains(newcube.name)) {
dont add to list
}
else {
cubelist.add(newcube);
}
with
boolean found = false;
for(Cube cube: cubelist){
if(cube.getName().equals(name)) {
found = true;
break;
}
}
if(!found) {
cubelist.add(newcube);
}
The idea is to use a boolean variable to track if a cube with the same name as that of the input name already exists in the list. For this, iterate cubelist and if a cube with the same name as that of the input name is found, change the state of the boolean variable and break the loop. If the state of the boolean variable does not change throughout the loop, add the cube to the list.
From the code in your question:
if(cubelist.contains(newcube.name)) {
// don't add to list
}
else {
cubelist.add(newcube);
}
Method contains in class java.utilArrayList is the way to go but you need to be aware that method contains [eventually] calls method equals of its element type. In your case, the element type is Cube. Therefore you need to add a equals method to class Cube. I don't know what determines whether two Cube objects are equal, but I'll guess, according to your question, that they are equal if they have the same name, even when they have different lengths. I will further assume that name cannot be null. Based on those assumptions, here is a equals method. You should add this method to class Cube.
public boolean equals(Object obj) {
boolean areEqual = false;
if (this == obj) {
areEqual = true;
}
else {
if (obj instanceof Cube) {
Cube other = (Cube) obj;
areEqual = name.equals(other.name);
}
}
return areEqual;
}
Now, in method main of class PartFive you can use the following if to add a Cube to the list.
if (!cubelist.contains(newcube)) {
cubelist.add(newcube);
}
You can check for duplicate names in the cubelist array using lambda expressions (for better readability):
boolean isNameAlreadyExisting = cubelist.stream()
.anyMatch(cube -> cube.getName().equals(newcube.getName())); // this is returning true if any of the cubelist element's name is equal with the newcube's name, meaning that the name is already existing in the cubelist
if (!isNameAlreadyExisting) {
cubelist.add(newcube);
}
One thing that you should do is to remove the while(true) instruction which causes an infinite loop.
Another suggestion is to display the name of objects contained by cubelist, to see that indeed the names are not duplicated:
cubelist.stream()
.map(Cube::getName)
.forEach(System.out::println);
I am writing test method like setTask(Task task). And Task object has several fields, e.g.
public String vehicle;
Method setTask should be used in different test-cases, so I'd like to have an options for this field to accept values:
null - the method should not do anything in this particulare case;
some string value - e.g. "", "Hello, World!", "Iso Isetta", ...
random - a value that indicates (as well as null indicates "no changes") that a random value should be selected for a drop-down list corresponding to this field.
So what can I do to make String to be SpecialString which could accept values null, random & some string value? (BTW: I don't want to set it to string value "RANDOM", and chech whether the value is equal to "RANDOM"-string)
UPDATE: I don't mean random like random value from a set of values, I mean random as well as null and this is for setTask() to handle random (select random from drop-down), and not to pass a random string from a set of values.
Pseudocode:
Task task = new Task();
task.vehicle = random; // as well as null
setTask(task)
in setTask(Task task):
if (task.vehicle == null) {
//skip
} else if (task.vehicle == random) {
// get possible values from drop-down list
// select one of them
} else {
// select value from drop-down list which is equal to task.vehicle
}
Don't assign a fixed String but use a Supplier<String> which can generate a String dynamically:
public Supplier<String> vehicleSupplier;
This, you can assign a generator function as you request:
static Supplier<String> nullSupplier () { return () -> null; }
static Supplier<String> fixedValueSupplier (String value) { return () -> value; }
static Supplier<String> randomSupplier (String... values) {
int index = ThreadLocalRandom.current().nextInt(values.length) -1;
return index > 0 && index < values.length ? values[index] : null;
}
In use, this looks like:
task.setVehicleSupplier(nullSupplier()); // or
task.setVehicleSupplier(fixedValueSupplier("value")); // or
task.setVehicleSupplier(randomSupplier("", "Hello, World!", "Iso Isetta"));
and you can get the String by
String value = task.vehicleSupplier().get();
or hide the implementation in a getter function
class Task {
// ...
private Supplier<String> vehicleSupplier;
public void setVehicleSupplier(Supplier<String> s) {
vehicleSupplier = s;
}
public String getVehicle() {
return vehicleSupplier != null ? vehicleSupplier.get() : null;
}
// ...
}
What you may want to do is to create an object that wraps a string as well as some information about whether or not it's a special value. Something along the lines of...
public class Special<T> {
public enum Type {
NOTHING, RANDOM, SPECIFIC
}
private final Type type;
private final T specificValue;
public Special(Type type, T specificValue) {
this.type = type;
this.specificValue = specificValue;
}
public Type getType() {
return type;
}
public T getSpecificValue() {
if (type != SPECIFIC) {
throw new IllegalStateException("Value is not specific");
}
return specificValue;
}
}
The class above could be used like so:
Special<String> a = new Special<>(Special.Type.NOTHING, null);
Special<String> b = new Special<>(Special.Type.SPECIFIC, "Hello");
if (b.getType() == Special.Type.RANDOM) {
// do something
}else if (b.getType() == Special.Type.SPECIFIC) {
String val = b.getSpecificValue();
// do something else
}
A slightly more polished variant of the thing above is probably the best way, but there is a way, a much uglier way, to do it using nothing but a String field.
What you could do is to have a "magical" string instance that behaves differently from all other string instances, despite having the same value. This would be done by having something like
static final String SPECIAL_VALUE_RANDOM = new String("random");
Note the use of the String constructor, which ensures that the string becomes a unique, non-interned instance. You can then say if (vehicle == SPECIAL_VALUE_RANDOM) { ... } (note the use of == instead of .equals()) to check if that specific instance (rather than any other string that says "random") was used.
Again, this is not a particularly good way of doing this, especially if you intend to do this more than once ever. I would strongly suggest something closer to the first way.
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 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());
I have a simple enum that I am iterating through to check if it contains a specific value. Here is my code -
private static boolean checkCountryCode(CountryCode countryCode) {
return Arrays.asList(CountryCodeList.values()).contains(countryCode.name());
}
This always returns false although the country code I am passing in the request is present in the list. In this case, I can't override equals since its a enum.
The countryCode in the method argument has the countryCode I am passing in the request. In my case, it is UA (Ukraine). The CountryCodeList is a list pre-populated with all the country codes in which our application runs. Some of them are on this page - http://countrycode.org/
Also, please note both CountryCode, and CountryCodeList are enums.
If CountryCodeList is enum, you can refactor you code to this
private static boolean checkCountryCode(CountryCode countryCode) {
try{
return CountryCodeList.valueOf(countryCode.name()) != null;
} catch (java.lang.IllegalArgumentException e) {
return false;
}
}