I have the following enum Group whick I am unsing to return the right id String depends on the parameter word2 String.
Code 1
public enum Group {
KG1("10460"),
KG2("10461"),
KG3("10462"),
KG4("10463");
private Group (String id){
this.id = id;
}
private final String id;
public String getId(){
return id;
}
public static String getGroupByWord2(String word2){
if(word2.contains("other company")){
return KG3.toString();
}else if(word2.contains("neu company")){
return KG1.toString();
}
return "";
}
#Override
public String toString() {
return getId();
}
}
Now I want to add the information other company, neu company to the enum fields. Therefore I changed the enum to this form below but I am facing probem
that it does not deliver the same result as of the code 1. How can add the Strings other company, neu company to enum fields to deliver the same result as in code 1?
Code 2
public enum Group {
KG1("10460", "neu company"),
KG2("10461", ""),
KG3("10462", "other company"),
KG4("10463", "");
private Group (String id, String word){
this.id = id;
this.word = word;
}
private final String id;
private final String word;
public String getId(){
return id;
}
public String getWord() {
return word;
}
public static String getGroupByWord2(String word2){
for (Group group : Group.values()) {
if (word2.contains( group.getWord())) {
return group.getId();
}
}
return null;
}
#Override
public String toString() {
return getId();
}
}
The code is actually working fine, the difference between the two snippets is equalsIgnoreCase() vs contains() and KG2 value is empty string which will match any non-null String value. Test and formatted code with changed contains() to equals() is below:
public static void main(String[] args) {
System.out.println(Group.getGroupByWord2("neu company")); //10460
System.out.println(Group.getGroupByWord2("other company")); //10462
System.out.println(Group.getGroupByWord2("non existing")); //null
System.out.println(Group.getGroupByWord2(" ")); //null
}
public enum Group {
KG1("10460", "neu company"),
KG2("10461", ""),
KG3("10462", "other company"),
KG4("10463", "");
Group(String id, String word) {
this.id = id;
this.word = word;
}
private final String id;
private final String word;
public String getId() {
return id;
}
public String getWord() {
return word;
}
public static String getGroupByWord2(String word2) {
for (Group group : Group.values()) {
if (word2.equalsIgnoreCase(group.getWord())) {
return group.toString();
}
}
return null;
}
#Override
public String toString() {
return getId();
}
}
In the first version, you check if word2 is either other company or neu company and return appropriate enum's String representation. But in the second one, you are checking word2.contains(group.getWord()) which is going to return true when group.getWord() is an empty string and hence you cannot make word an empty string for the rest of the enums.
If empty strings are not one of the valid cases (valid word2), then just add a condition to check for empty string
if (!group.getWord().isEmpty() && word2.contains(group.getWord()))
One more difference is that at the end (when no match is found) you return null as opposed to an empty string in version 1.
Related
I have enum:
public enum Enumz{
FIRST_VALUE(0, "one"),
SECOND_VALUE(1, "two"),
THIRD_VALUE(2, "three")
private int id;
private String name;
}
How can I find enum value if my String value match with enum string name? For example: if I have String = "two" I need to get ENUMZ.SECOND_VALUE.
public enum Enumz {
FIRST_VALUE(0, "one"),
SECOND_VALUE(1, "two"),
THIRD_VALUE(2, "three");
private int id;
private String name;
Enumz(int id, String name) {
this.id = id;
this.name = name;
}
public static Enumz fromString(String text) {
for (Enumz b : Enumz.values()) {
if (b.name.equalsIgnoreCase(text)) {
return b;
}
}
return null;
}
}
class Sample{
public static void main(String[] args) {
System.out.println(Enumz.fromString("two"));
}
}
You can implement your own method inside enum and call that method every time you want enum using String.
Above code will printing an output as below
OUTPUT
SECOND_VALUE
You can use Java 8 stream alternative to for loop
String serachValue = "two";
Enumz enumz = Arrays.stream(Enumz.values())
.filter(v -> serachValue.equalsIgnoreCase(v.name))
.findFirst().orElse(null);
Good practice is always put it as a static method into the ENUM itself as explained by other #Sagar Gangwal.
public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2),
private Integer id;
EnumCountry(Integer value) {
this.id = value;
}
public Integer getId() {
return id;
}
#Nullable
public static EnumCountry fromId(Integer id) {
for (EnumCountry at : EnumCountry.values()) {
if (at.getId().equals(id)) {
return at;
}
}
return null;
}
}
I have the code like above.
How can I get Enum Id using its Enum Name.
You can simply add a method like below -
public static int getId(String enumCountryName) {
return EnumCountry.valueOf(enumCountryName).getId();
}
So the complete class will be like this -
public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2);
private Integer id;
EnumCountry(Integer value) {
this.id = value;
}
public Integer getId() {
return id;
}
#Nullable
public static EnumCountry fromId(Integer id) {
for (EnumCountry at : EnumCountry.values()) {
if (at.getId().equals(id)) {
return at;
}
}
return null;
}
public static int getId(String enumCountryName) {
return EnumCountry.valueOf(enumCountryName).getId();
}
}
It is as simple as calling its getId() method:
Ethiopia.getId()
Or:
Tanzania.getId()
Or, assuming you meant you have the string "Ethiopia", then you can also do EnumCountry.valueOf("Ethiopia").getId(). Hope that answers your question!
You can't because their types are incompatible - i.e. String vs Integer. On the other hand, you can add a method that returns a String that combines name and id:
public enum EnumCountry implements EnumClass<Integer> {
Ethiopia(1),
Tanzania(2); // replaced comma with semicolon
private Integer id;
// ...
public String getNameId() {
// returns "Ethiopa 1"
return name() + " " + id;
}
// ...
}
If name is present as String, simply do this,
int getId(String name){
EnumCountry country = EnumCountry.valueOf(name);
return country.getId();
}
I have a String in this format (including curly brackets):
{id=123, vehicle_name=Tesla Model X, price=80000.00, ... }
What is the appropriate Java object to represent this String, and how can I convert it to that object?
I would like to be able to query the object to retrieve its values easily, eg. obj.get("vehicle_name"). I've tried converting it to JSON using JSONObject however this expects colons as the delimiters between keys and values, rather than the equals sign.
String itself is a java object.
Parsing String and filling up a java object is not clean.
You can create a java pojo Vehicle with attributeS like id,
vehicle_name etc. Assuming your String will always follow a same
pattern.
Parse the String, and fill this Vehicle pojo.
Below is just a simple example, on how to do it :-
public class Test {
public static void main(String[] args){
String text="{id=123, vehicle_name=Tesla Model X, price=80000.00}";
text=text.replaceAll("[{}]", "");
String[] commaDelimitArray=text.split(",");
Vehicle vehicle=new Vehicle();
for(int i=0;i<commaDelimitArray.length;i++){
String[] keyValuePair=commaDelimitArray[i].split("=");
String key=keyValuePair[0].trim();
String value=keyValuePair[1].trim();
if("id".equals(key)){
vehicle.setId(value);
}
else if("vehicle_name".equals(key)){
vehicle.setVehicleName(value);
}
else if("price".equals(key)){
vehicle.setPrice(value);
}
}
System.out.println(vehicle.getId()+" |"+vehicle.getVehicleName());
}
static class Vehicle{
private String id;
private String vehicleName;
private String price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVehicleName() {
return vehicleName;
}
public void setVehicleName(String vehicleName) {
this.vehicleName = vehicleName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
This appears to be an assignment in creating Object classes. If so, you want to create something like this:
public class Car {
int id;
String name;
double price;
//include any other necessary variables
public Car(int id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
//include any other variables in constructor header and body
}
public void setID(int newID) {
id = newID;
}
public int getID() {
return id;
}
//add getters and setters for other variables in this same manner
}
Note that you could alternatively create a constructor that takes no parameters and initializes variables to default values, then set the values individually using the setter methods.
In your main class, what you want to do is extract the appropriate substrings from your String to pass to the constructor (or setters). There are various ways of doing this (you can read about some ways here); I would personally recommend using regular expressions and a Matcher.
If I had such a string which needed to be converted to an object I would create a class with a static method which returns a Vehicle object. Then you can do whatever you want with that object. A few getters and setters and you should be good to go.
I have come up with some code which should work as you expect if I have understood your question :)
There is quite a few comments so this should help you understand the code logic.
The Vehicle Class is where all parsing happens in the static method named createVehicle(String keyValueString).
The main class:
import java.util.ArrayList;
import java.util.List;
public class main {
public static void main(String[] args) {
String vehicleString = "{id=123, vehicle_name=Tesla Model X, price=80000.00}";
List<Vehicle> vehicles = new ArrayList<Vehicle>();
Vehicle vehicle;
// call the static method passing the string for one vehicle
vehicle = Vehicle.createVehicle(vehicleString);
// if the id is -1, then the default constructor fired since
// there was an error when parsing the code.
if(vehicle.getId() == -1 ) {
System.out.println("Check your data buddy.");
} else {
vehicles.add(vehicle);
}
for(Vehicle v : vehicles){
System.out.println("Vehicle id: " + v.getId());
System.out.println("Vehicle name: " + v.getVehicle_name());
System.out.println("Vehicle price: " + v.getPrice());
System.out.println();
}
}
}
The Vehicle Class:
import java.math.BigDecimal;
public class Vehicle {
// declare your attributes mapped to your string
private int id;
private String vehicle_name;
private BigDecimal price;
// Start Constructor
// Default Constructor
public Vehicle() {
this.setId(-1);
this.setVehicle_name("Empty");
this.setPrice(new BigDecimal(0.00));
}
public Vehicle(int id, String vehicle_name, BigDecimal price) {
this.setId(id);
this.setVehicle_name(vehicle_name);
this.setPrice(price);
}
// End Constructor
// Start Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getVehicle_name() {
return vehicle_name;
}
public void setVehicle_name(String vehicle_name) {
this.vehicle_name = vehicle_name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
// End Getters and Setters.
// Start Methods and Functions
// Given a string returns a string array split by a "," and with
// "{}" removed.
private static String[] splitString(String keyValueString) {
String[] split;
// Clean string from unwanted values
keyValueString = keyValueString.replaceAll("[{}]", "");
split = keyValueString.split(",");
return split;
}
// Add a vehicle given a formatted string with key value pairs
public static Vehicle createVehicle(String keyValueString) {
int id = 0;
String vehicle_name = "";
BigDecimal price = null;
String[] split;
Vehicle vehicle;
split = splitString(keyValueString);
// Loop through each keyValue array
for(String keyValueJoined : split){
// split the keyValue again using the "="
String[] keyValue = keyValueJoined.split("=");
// remove white space and add to a String variable
String key = keyValue[0].trim();
String value = keyValue[1].trim();
// check which attribute you currently have and add
// to the appropriate variable
switch(key){
case "id":
id = Integer.parseInt(value);
break;
case "vehicle_name":
vehicle_name = value;
break;
case "price":
try {
price = new BigDecimal(Double.parseDouble(value));
} catch (NumberFormatException e) {
e.printStackTrace();
}
break;
default:
System.out.println("Attribute not available");
return null;
}
}
// if any of the values have not been changed then either the
// data is incomplete or inconsistent so return the default constructor.
// Can be removed or changed if you expected incomplete data. It all
// depends how you would like to handle this.
if(id == 0 || vehicle_name.equals("") || price == null){
vehicle = new Vehicle();
} else {
//System.out.println(id);
vehicle = new Vehicle(id, vehicle_name, price);
}
return vehicle;
}
// End Methods and Functions
}
The program, given the string provided, returns the following when accessing the newly created object attributes using the getters:
Vehicle id: 123 Vehicle name: Tesla Model X Vehicle
price: 80000
Hope this helps.
First, thank you for your help!!
What I want to make with an Enumeration class is a Menu of a restaurant. The menu components have its own id which is number, and name.
001("Pasta"),
002("Pizza"),
003("Nuddle"),
004("Steak"),
005("Rice")
Above code my first idea but, I got errors, so I thought only String value can be the components of Enumeration. So, I changed the code like below but it generated error again.
"001"("Pasta"),
"002"("Pizza"),
"003"("Nuddle"),
"004"("Steak"),
"005"("Rice")
The numbers are just IDs of food, so it can have String type. How can I make it?
Enums names cannot start with numbers. If you want to use Enums, I would suggest to use something like this:
public enum Food {
PASTA("Pasta", 1),
PIZZA("Pizza", 2);
/** state variables */
private String name;
private int id;
/** Constructor */
Food(String name, int id) {
this.name=name;
this.id=id;
}
/** Accessors */
public String getName() {
return name;
}
public int getId() {
return id;
}
}
you can use in this way. Or how about add some character like...F001, F002
public class Tester {
static enum Food {
PASTA("001"), PIZZA("002"), NOODLE("003");
private String number;
Food(String number){
this.number = number;
}
public String getNumber(){
return this.number;
}
}
public static void main(String[] args) {
System.out.println( Food.PIZZA.getNumber());
}
}
You can do something like this. First create a static map and put number and string value as a key value pair and write a utility to retrieve a food value based on the given number key value after creating your constructor to populate both fields.
public enum MenuEnum {
ONE(1, "Pasta"), TWO(2, "Pizza"), THREE(3, "Noodle");
private int number;
private String name;
private MenuEnum(int number, String name) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public int getNumber() {
return number;
}
public String getFoodByNumber(int key) {
return foodMap.get(key) != null ? foodMap.get(key) : null;
}
private static final Map<Integer, String> foodMap = new HashMap<Integer, String>();
static {
for (MenuEnum val : MenuEnum.values()) {
foodMap.put(val.getNumber(), val.getName());
}
}
I am using a custom class object as the key for a HashMap. In this class definition, I have overridden the equals() and hashCode() methods.
public class TimeTableDataModel {
Map <Course, List <Timings>> tm;
TimeTableDataModel() {
tm = new HashMap<>();
}
void addCourseItem(Course course) {
tm.put(course, new ArrayList<Timings>());
}
void addNewTimeTableItem(Course course, Timings newTiming) {
List <Timings> t;
if(!tm.containsKey(course)) {
addCourseItem(course);
}
t = tm.get(course);
t.add(newTiming);
tm.put(course, t);
}
public static final class Course {
private final String courseCode;
private final String courseName;
private final String section;
private final String group;
Course(String code, String courseName, String section, String group) {
this.courseCode = code;
this.courseName = courseName;
this.section = section;
this.group = group;
}
public String getCourseCode() { return courseCode; }
public String getCourseName() { return courseName; }
public String getSection() { return section; }
public String getGroup() { return group; }
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Course)) {
return false;
}
Course otherObj = (Course) obj;
return Objects.equals(courseCode,otherObj.courseCode)
&& Objects.equals(courseName, otherObj.courseName)
&& Objects.equals(section, otherObj.section)
&& Objects.equals(group, otherObj.group);
}
#Override
public int hashCode() {
return Objects.hash(courseCode, courseName, section, group);
}
}
public static class Timings {
String time;
String day;
String room;
Timings(String time, String day) {
setTime(time);
setDay(day);
}
public String getTime() { return time; }
public String getday() { return day; }
public void setTime(String time) { this.time = time; }
public void setDay(String day){this.day = day;}
}
}
In above code I have created Course class to be used as the key for the HashMap and using a List<Timings> for values. What I intend is to get a List of timings when a Course is passed to hm.get(course). So far I can get a keyset then sequentially get values for each course.
for(Course c : timetable.tm.keySet()) {
System.out.println(c.getCourseCode() + " " + c.getCourseName());
for(Timings t : timetable.tm.get(c)) {
System.out.println(t.time + " " +t.room + " "+ t.day);
}
};
Here's the code that populates the HashMap
static TimeTableDataModel timetable = new TimeTableDataModel();
Course course = new Course(courseCode,null,section,group);
Timings dt = new Timings(time, getDayOfWeek(i));
dt.room = roomNo;
timetable.addNewTimeTableItem(course, dt);
So to get the timings for a particular course I have to traverse the whole HashMap until the desired course Key is found. What I want is a way to distinguish between each course object contained in the HashMap Key, so I can get Timings for any random course without traversing the whole KeySet.
Thanks in advance. Please ask if somethings is unclear in code
Problem what I see here is
if(!tm.containsKey(course)){
addCourseItem(course);
}
and
if (this == obj) {
return true;
}
because you are comparing the object. Since both are same class objects equals will always return true and map concludes it as duplicate key.