I have a Hashtable of type Hashtable
I've loaded several strings as keys, one of which is "ABCD"
However, later when I go to look up "ABCD", the Hashtable returns null instead of the associated object. Further the keyset contains "ABCD", but a request to containsKey("ABCD") returns false.
Is this because String objects are inherently different objects?
If so, what is the write way to store information in a Hashtable if I want to use Strings as keys?
public class Field {
private String name;
private DataType dataType;
public Field(String name, DataType dataType) {
this.name = name;
this.dataType = dataType;
}
public String getName() {
return name;
}
public DataType getDataType() {
return dataType;
}
public String toString() {
return name;
}
}
public class Record {
private Hashtable<String, Data> content;
public Record(Field[] fieldList) {
this.fieldList = fieldList;
content = new Hashtable<String, Data>();
System.out.println(fieldList.length);
for(Field f : fieldList) {
content.put(f.getName(), new Data());
}
}
public void add(String field, String s) {
// ERROR OCCURS HERE IN THIS METHOD !!!
System.out.println(field);
for(String ss : content.keySet()) {
System.out.print(" [ " + ss + " ] ");
}
System.out.println();
System.out.println(content.containsKey(field));
System.out.println(content.get(field));
content.get(field).add(s);
}
}
public class Data {
private Vector<String> lines;
private int index;
public Data() {
lines = new Vector<String>();
index = 0;
}
public void add(String s) {
System.out.println("adding");
lines.add(s);
}
public String nextLine() {
try {
return lines.elementAt(index++);
} catch (ArrayIndexOutOfBoundsException aioobe) {
return null;
}
}
}
Works for me!
import java.util.Hashtable;
public class StrMap {
public static void main(String[] args) {
Hashtable<String,Object> map = new Hashtable<String,Object>();
map.put("ABCD", "value");
System.err.println(map.containsKey("ABCD"));
}
}
Yo have probably made some other error. Reduce the problem to the smallest complete compilable program that still demonstrates the problem. You'll probably find the problem straight away. If you don't, at least you will have a question that we can answer.
(Also Map and HashMap is that way to go. Hashtable is useful if you are using a pre-Java 2 API (Java 2 is comfortably over a decade old now!).)
Hashtable is a Java 1.0 data structure. I wonder why you're not using a Map?
If java.lang.String is the key type, I'd say you're being hosed by something else that's impossible to guess without posting code.
It's hard to pinpoint the root cause without an SSCCE from your side.
At least, the common causes are:
You're not using the Hashtable you think you're using. System.out.println() it to verify.
The String is actually in a different case, e.g. "ABcD" instead of "ABCD".
The String is surrounded with some whitespace which you needs to trim() first.
That said (and unrelated to the actual problem), I strongly recommend to use the improved HashMap instead of the legacy Hashtable. Here's a Sun tutorial about maps.
Can you also post the exact output you get from the following method when field is "ABCD"?
public void add(String field, String s) {
// ERROR OCCURS HERE IN THIS METHOD !!!
System.out.println(field);
for(String ss : content.keySet()) {
System.out.print(" [ " + ss + " ] ");
}
System.out.println();
System.out.println(content.containsKey(field));
System.out.println(content.get(field));
content.get(field).add(s);
}
Related
So for the below question, I tried to search online but I couldn't find the answer to it. I am working in Java language.
So I currently have a class, lets say:
public Employee(String emp_id, String location, String name)
{
this.emp_id = emp_id;
this.location = location;
this.name = name;
}
I have created multiple objects of Employee, and I have saved it in an arrayList. Now, I the user will ask which employees are located in New York, or they can ask which employees are named John.
So they can enter location New York. I need to read in the user's request, first identify what they are trying to search, and then see if there are any matching Employees in the array.
I have read in the command, and saved it in an array of strings called Search. The first index holds the name of the field/property of the object, and the second index will hold what the user actually wants to check.
String[] search = new String[] { "location", "New York" }
I was thinking for doing this:
for(Employee e: empList)
if(e.search[0].equals(search[1]))
System.out.println(e)
However, I am not able to do this, since search[0] is not a property name for the Employee object. I am getting this error: error: cannot find symbol.
Is there a way for me to access the object property without the actual name, meaning the name is saved in another String variable?
Please let me know. Appreciate your help.
Thank you.
What you are looking for is the Reflection API. Here's a simple example of how you might achieve what you need. Notice that we can query the class for its Fields and Methods. We can then do checks on Field types or Method return types. Reflection is not for the faint of heart but it can give you some extremely dynamic code.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Employee {
public String name;
public int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
public static void main(String[] args) throws Exception {
Employee e1 = new Employee("Nick", 30);
Class<?> c = e1.getClass();
Field f = c.getField("name");
System.out.print("Type: ");
System.out.println(f.getType());
System.out.print("Object: ");
System.out.println(f.get(e1));
System.out.println();
System.out.println("Methods: ");
Method[] methods = c.getMethods();
for(int i = 0; i < methods.length; i++) {
System.out.print("Name: ");
System.out.println(methods[i].getName());
System.out.print("Return type: ");
System.out.println(methods[i].getReturnType());
// imagine this value was set by user input
String property = "name";
if( methods[i].getName().toLowerCase().equals("get" + property) ) {
System.out.print("Value of " + property + " is: ");
System.out.println(methods[i].invoke(e1));
}
}
}
}
You could write your class to allow querying in this way, by wrapping a Map (or a Properties if you prefer:
public class Employee {
private Map<String,String> properties = new HashMap<>();
public Employee(String emp_id, String location, String name) {
properties.put("emp_id", empt_id);
properties.put("location", location);
properties.put("name", name);
}
public String getProperty(String key) {
return properties.get(key);
}
}
You can expose the fields as getters if you like:
public String getName() {
return this.getProperty("name");
}
The opposite way around, of course, is to explicitly write a getProperty(String) to access fields:
public String getProperty(String key) {
switch(key) {
case "name":
return this.name;
case "empId":
return this.empId;
case "location":
return this.location;
default:
throw new NoSuchFieldException; // or return null, or whatever
}
}
This may seem long-winded, but it's pretty easy and effective.
You can also use Reflection to work with the class at runtime. This is not recommended for new programmers - not because it is difficult as such, but because usually there's a cleaner way. And it subverts Java's access control features (e.g. it can read private fields).
Reflection includes techniques such as Class<?> c = e1.getClass(); Field f = c.getField("name"); -- there are no checks at compile time that e1 has a field called name. It will only fail at runtime.
If you're willing to use the Bean method naming conventions -- mostly simply that getName() is an accessor for a field called name -- then you could use Apache BeanUtils to work with the object. This is also Reflection, but it's wrapped in a more task-centric API.
String name = PropertyUtils.getProperty("name");
... this will:
call getName() and return the result, if getName() exists
throw NoSuchMethodException if there is no getName() method
other exceptions for other failures (see the JavaDoc)
So you could write:
public boolean isMatch(Employee employee, String[] search) {
String key = search[0];
String expectedValue = search[1];
try {
String actual = PropertyUtils.getProperty(key);
return(Objects.equals(actual,expected)); // Objects.equals is null-safe
} catch (NoSuchMethodException e) {
return false;
}
}
This is just pseudocode. But here you are getting each Employee object at index i and getting the name returned in the form of a string from this employee at index i.
for (int i = 0; i < empList.size(); i++)
{
if (empList.get(i).getId().equals(search[1]) || empList.get(i).getName().equals(search[1]) || empList.get(i).getLocation().equals(search[1]))
return true;
}
So basically, iterate through your list of objects Employee. At each employee, getName() returns the string value of the name of this Employee.
That is how you access the properties, with your getter method.
public String getName()
{
return this.name;
}
You can use the getFields() method if the Class, although I recommend you a simpler method if the class have so little properties, you can just use the or operation to achieve this:
for(Employee e: empList)
if(e.getLocation().equals(Search[1])||e.getName().equals(Search[1]))
System.out.println(e)
Using the getFields() method:
String searchValue="The string you have to search";
for(Employee e: empList){
List<Field> selectedFields=new ArrayList<Field>();
for (int i = 0; i < e.getClass().getFields().length; i++) {
if(e.getClass().getFields()[i].getType().getName().equals("String")){
selectedFields.add(e.getClass().getFields()[i]);
}
}
for(Field f:selectedFields){
if(f.get(e).equals(searchValue)){
System.out.println(e);
}
}
}
}
As mentioned in other answers: this can be solved with reflection. Another approach with some java8-sugar:
public static void main(String[] args) {
List<Employee> unfilteredList = new ArrayList<>();
// ... Add the employees
String[] fieldAndExpectedValue = new String[] { "location", "Narnia-City" };
List<Employee> filteredList = unfilteredList.stream().filter(
employee -> objectHasFieldWithValue(employee, fieldAndExpectedValue[0], fieldAndExpectedValue[1]))
.collect(Collectors.toList());
// ...
}
private static <INSTANCE, FIELDVALUE> boolean objectHasFieldWithValue(INSTANCE o,
String fieldName, FIELDVALUE expectedValue) {
try {
Field f = o.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
if (f.getType().isInstance(expectedValue) && expectedValue.equals(f.get(o))) {
return true;
}
} catch (Exception exc) {
exc.printStackTrace();
}
return false;
}
It's weird that all the answers focus on reflection. Design wise, you should be using getters to solve your problem. It is true that you need to use reflection to retrieve a property without any extra logic in that section of code, but your problem should rely on improving the searching logic rather than exposing fields and breaking SOLID OOP design.
From the looks of it you want a simple solution for searching through an array of objects and checking if the a property matches a certain value.
This would be an answer to that question:
///public class Employee {
public bool doesEmployeeMatch(String property, String value){
switch(property){
case "location": return value.equals(this.location);
break;
case "name": return value.equals(this.name);
break;
default: System.out.println("Invalid parameter");
break;
}
}
///where ever you're searching through empList
for(Employee e: empList)
if(e.doesEmployeeMatch(search[0],search[1])){
System.out.println(e);
break;
}
But that isn't how the question should be formed. Best way of forming the question would be "I need to determine the search parameter, then find the Employees that match the value of my parameter." That means you should have two steps to logically handle this actions. First figure out what field you want to find, then find all the employees that have the expected value on said field.
So what would that look like?
First you'll need some getter functions.
public class Employee {
private String emp_id, location, name;
public Employee(String emp_id, String location, String name) {
this.emp_id = emp_id;
this.location = location;
this.name = name;
}
public String getEmp_id(){
return this.emp_id;
}
public String getLocation(){
return this.location;
}
public String getName(){
return this.Name;
}
}
Next up you need to add logic for determining which getter to use.
///sorry I just threw a method name out for you
public bool findEmployeeMatch(String[] search){
switch(search[0]){
case "location":
break;
case "name":
break;
default:
break;
}
Finally add some lambda expressions to impress the masses.
public bool findEmployeeMatch(String[] search, empList){
///other code maybe?
switch(search[0]){
case "location": Arrays.stream(empList).forEach(e)->
if(e.getLocation().equals(search[1])){
System.out.println(e);
}
break;
case "name": Arrays.stream(empList).forEach(e)->
if(e.getName().equals(search[1])){
System.out.println(e);
}
break;
case "emp_id": Arrays.stream(empList).forEach(e)->
if(e.getEmp_List().equals(search[1])){
System.out.println(e);
}
break;
default: System.out.println("Invalid parameter");
break;
}
I can't see why there would be a reason to not check for what field they would want, as using reflection is costly and seeing how this is an app that expects users to search for data in a backend, whether for work or school, I do not believe reflection is the thing you want to be using.
I suggest not to use reflection API at all. It is messy and not type safe.
Instead use Functional interface Java 8 provides or similar constructs if you are not using Java 8. Here is a cleaner type safe solution using Java 8:
public class Search<T> {
private T searchValue = null;
private Function<Employee, T> getter = null;
public Search(T searchValue, Function<Employee, T> getter) {
this.searchValue = searchValue;
this.getter = getter;
}
public T getSearchValue() {
return searchValue;
}
public void setSearchValue(T searchValue) {
this.searchValue = searchValue;
}
public Function<Employee, T> getGetter() {
return getter;
}
public void setGetter(Function<Employee, T> getter) {
this.getter = getter;
}
}
public Optional<Employee> find(List<Employee> empList, Search<?> search){
for (Employee e : empList){
if ( Objects.equals( search.getGetter().apply(e), search.getSearchValue() ) ) return Optional.of(e);
}
return Optional.empty();
}
And you can search like this:
find( empList, new Search<>("Mark", Employee::getName ) ) //finds Employee with name Mark
find( empList, new Search<>("Toronto", Employee::getLocation ) ) //finds Employee with location in Toronto
Update:
Here is method that maps user specified field name to actual Search:
public static Search<String> create(String searchValue, String fieldName){
if ( "name".equalsIgnoreCase(fieldName) ) return new Search<>(searchValue, Employee::getName );
else if ( "location".equalsIgnoreCase(fieldName) ) return new Search<>(searchValue, Employee::getLocation );
else throw new IllegalArgumentException("Unsupported fieldName: " + fieldName);
}
find(empList, Search.create("Toronto", "location" ) )
I want to sort an ArrayList of objects on a specific field using a given RuleBasedCollator.
For example, we have a list of Thing objects:
public Thing {
public String name;
public String type;
}
List<Thing> things = new ArrayList<Thing>();
RuleBasedCollator ruleBasedCollator = new RuleBasedCollator("< Table < Plate < Fork < Knife");
Now, after having created Thing objects and added them to the things list, I want to sort this list, getting first things of type "table" and last things of type "knife".
Does anyone know how to do it?
You can try something like this, instead of using compareTo in compare method of Comparator you can call RuleBasedCollator's compare.
mQueue.sort((o1, o2) -> {
if (o1.getDescription().getTitle() != null && o2.getDescription().getTitle() != null) {
return mRuleBasedCollator.compare(o1.getDescription().getTitle().toString(),
o2.getDescription().getTitle().toString());
} else {
return 0;
}
});
As far as I understand a RuleBaseCollator is intended for sorting Strings, at least i says so in the Collator class which is the super class. I would instead use a Comparator, something like this:
public class ThingSorter {
public enum ThingType{
//wanted sort order, sort on ordinal :
//Table < Plate < Fork < Knife
TABLE, PLATE, FORK, KNIFE
}
public static class Thing {
private String name;
private ThingType type;
public Thing(String name, ThingType tt) {
this.name = name;
type = tt;
}
public String toString() {
return name + " [" + type + "]";
}
}
public static class MyThingComparator implements Comparator<Thing> {
#Override
public int compare(Thing t1, Thing t2) {
return t1.type.ordinal() - t2.type.ordinal();
}
}
public static class MyReverseThingComparator implements Comparator<Thing> {
#Override
public int compare(Thing t1, Thing t2) {
return t2.type.ordinal() - t1.type.ordinal();
}
}
public static void main(String[] args) throws ParseException {
List<Thing> things = new ArrayList<Thing>();
things.add(new Thing("One", ThingType.KNIFE));
things.add(new Thing("Two", ThingType.FORK));
things.add(new Thing("Three", ThingType.PLATE));
things.add(new Thing("Four", ThingType.TABLE));
System.out.println("unsorted:\n" + things);
Collections.sort(things, new MyThingComparable());
System.out.println("sorted:\n" + things);
Collections.sort(things, new MyReverseThingComparable());
System.out.println("sorted:\n" + things);
}
}
The names are are not involved in the sorting in this case just the type (and the ordinal in the type)
You could certainly use the TreeMap or enum as the previous answers suggest; a rather simpler alternative is to use just a custom compatator, without the enum. If you're using Java 8 you can get it down to a single line:
Collections.sort(things,
(Thing t1, Thing t2)->ruleBasedCollator.compare(t1.type, t2.type) );
The pre-8 version would do the same thing with an anonymous Comparator
I finally found a solution using a TreeMap. I use the "type" property for the key and a list of Thing for the value. Instead of using a RuleBasedCollator, I created a ListBasedCollator extending Collator, because RuleBasedCollator rules work on characters but not on words.
public class ListBasedCollator extends Collator {
private List<String> list;
public ListBasedCollator(String[] array) {
list = Arrays.asList(array);
}
#Override
public int compare(String source, String target) {
if(!list.contains(target)) {
return 1;
}
if(!list.contains(source)) {
return -1;
}
return Integer.valueOf(list.indexOf(source)).compareTo(Integer.valueOf(list.indexOf(target)));
}
#Override
public CollationKey getCollationKey(String source) {
return null;
}
#Override
public int hashCode() {
return 0;
}
}
Here is how I construct the TreeMap:
String[] sortingList = {"TABLE", "PLATE", "FORK", "KNIFE"};
ListBasedCollator listBasedCollator = new ListBasedCollator(sortingList);
Map<String, List<Thing>> thingMap = new TreeMap<String, List<Thing>>(listBasedCollator);
So, the thingMap will always be sorted by type using the listBasedCollator.
And I can also sort alphabetically the list of things for each different type.
How to print any class instance in Java? Similar to JSON.stringify() in Javascript. Not necessary JSON, any format of output will do.
public class User {
public String name, password;
public int age;
public ArrayList<String> phones;
public static void login() {
//do something
}
}
User X = new User;
X.name = "john connor";
X.password = "skynet";
X.age = "33";
X.phones.add("1234567");
X.phones.add("7654321");
System.out.println(printClass(X))
Should output something like:
{ name:"john connor", password: "skynet", age: "33", phones:
["1234567", "7654321"], login: void function() }
You can use Apache's commons-lang's ToStringBuilder.reflectionToString
Of course, reflection is slow, so only do this with your test code. for normal use, please use eclipse's "Source" menu -> generate toString() (or intellij's generate toString()) which gives you a decent string.
There could be many ways to achieve what you need. Though i would be interested in why you need.
Override the toString() method.
see: http://www.javapractices.com/topic/TopicAction.do?Id=55
If the generation algorithm gets too long, then consider a separate class say UserPrettyPrinter.
public interface UserPrettyPrinter {
string print(User);
}
public class PrintUserInJSON implements UserPrettyPrinter {
string print(User user) {
//implement the algo here
}
}
you can also implement:
public class PrintUserInXML implements UserPrettyPrinter {
string print(User user) {
//implement the algo here
}
}
Either in conjugation to number-2 or as a standalone class, you can write
public class PrintObjectBasicAlgo {
String print(Object obj) {
/* i write pseudo code here. just ask if you cannot implement this
this would help: http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html
Class class = Obj.getClass();
Filed[] allVariables = class.getAllFieldsByReflection();
ArrayList<String> keys = new ArrayList<String>;
ArrayList<String> values = new ArrayList<String>;
for(Field field : allVariables) {
Object value = reflectionGetValueOfField( field, obj );
keys.add( field.getName());
values.add(value.toString());
}
now that you have the keys and values, you can generate a string in anyway you like
*/
}
}
You may see Visitor Pattern. it might be helpful.
You have two options here. The simple one is just to override the toString function for your class. I dont see why you dont do this really. In this case its as simple as
String toString(){
return "{ name:\""+name+", password: \""+passowrd....
}
The second option is to use reflection. This would be slightly (though not really) better if you had some sorta external class used for "printing classes". The pseudo code for that would be
StringBuilder s = new StringBuidler();
for(Field f : fields){
s.append(f.getName() + "\" :\"" + f.get()+ "\"");
}
return s.toString();
However this would be costly as reflection always is. Also if you just properly override the toString functions in the first place your printClass function could literally just be
String printClass(Object o){ return o.toString();}
Which of course again begs the question of why do you need a printClass function?
One option is to use Google Gson.
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
class Project {
private int year = 1987;
private String name = "ROBOCOP-1";
private boolean active = false;
private List<String> list = new ArrayList<String>() {
{
add("PROTECT THE INNOCENT");
add("UPHOLD THE LAW");
add("SERVE THE PUBLIC TRUST");
add("CLASSIFIED");
}
};
}
public class GsonExample {
public static void main(String[] args) {
Project obj = new Project();
Gson gson = new Gson();
String json = gson.toJson(obj);
System.out.println(gson.toJson(obj));
}
}
I am refactoring some old code and find a class "Tags" containing string constants, most of them tags used by some XML-Parser-Handlers. But also for serialising data. They are defined blank:
public static String PROXY, NAME, X, Y, KEY, ... CODES;
and initialized by their own name:
static {
Field[] fields = Tags.class.getFields();
for (int i = 0; i < fields.length; ++i) {
try {
// init field by its lowercased name
String value = fields[i].getName().toLowerCase();
fields[i].set(null, value);
} catch (Exception e) {
// exception should not occur, because only strings over here.
e.printStackTrace();
}
}
}
Does it make sense in your opinion?
Pros:
all tags in one place
guaranteed correspondence between name & value (no mistyping)
support by IDE autocompletion when typing
Cons:
not really constants (not final)
readability -- to just use the string literals "proxy", "name" etc. would be more straightforward
the initialisation by reflection consumes processing time -- delays startup time
So -- keep it or refactor it?
You can replace these constants by an enum and still keep the advantages you've listed:
public enum Tags {
PROXY("proxy"),
NAME("name"),
X("x"),
Y("y");
public final String value;
private Tags(String value) {
this.value = value;
if (!value.equals(name().toLowerCase())) {
throw new RuntimeException("Value and name do not match");
}
}
public static void main(String[] args) {
for (Tags tag : Tags.values()) {
System.out.println(tag + "\t" + tag.value);
}
}
}
In the code above, the test value.equals(name().toLowerCase()) is not necessary but you seem concerned about mistyping errors
Try this:
enum Enum {
PROXY, NAME, X, Y;
public String toString() {
return name().toLowerCase();
}
}
or this:
public enum Tags {
proxy, name, x, y
}
enum generalInformation {
NAME {
#Override
public String toString() {
return "Name";
}
},
EDUCATION {
#Override
public String toString() {
return "Education";
}
},
EMAIL {
#Override
public String toString() {
return "Email";
}
},
PROFESSION {
#Override
public String toString() {
return "Profession";
}
},
PHONE {
#Override
public String toString() {
return "Phone";
}
}
}
I have that information are avaiable in enum.
How to print all enum values like: print.generalInformation?
That outputs:
Name
Education
Email
Phone
How to pass that enum generalInformation as an arg in another function?
System.out.println(java.util.Arrays.asList(generalInformation.values()));
Your second part... Just the same as an interface or a class
Firstly, I would refactor your enum to pass the string representation in a constructor parameter. That code is at the bottom.
Now, to print all enum values you'd just use something like:
// Note: enum name changed to comply with Java naming conventions
for (GeneralInformation info : EnumSet.allOf(GeneralInformation.class)) {
System.out.println(info);
}
An alternative to using EnumSet would be to use GeneralInformation.values(), but that means you have to create a new array each time you call it, which feels wasteful to me. Admittedly calling EnumSet.allOf requires a new object each time too... if you're doing this a lot and are concerned about the performance, you could always cache it somewhere.
You can use GeneralInformation just like any other type when it comes to parameters:
public void doSomething(GeneralInformation info) {
// Whatever
}
Called with a value, e.g.
doSomething(GeneralInformation.PHONE);
Refactoring using a constructor parameter
public enum GeneralInformation {
NAME("Name"),
EDUCATION("Education"),
EMAIL("Email"),
PROFESSION("Profession"),
PHONE("Phone");
private final String textRepresentation;
private GeneralInformation(String textRepresentation) {
this.textRepresentation = textRepresentation;
}
#Override public String toString() {
return textRepresentation;
}
}
With your current values, you could actually just convert the name to title case automatically - but that wouldn't be very flexible for the long term, and I think this explicit version is simpler.
Since Java 8 I would suggest the following solution:
public static String printAll() {
return Stream.of(GeneralInformation.values()).
map(GeneralInformation::name).
collect(Collectors.joining(", "));
}
In applications, it's good practice to separate data from presentation. It allows the data to be used in different user interfaces, it makes the data objects more lightweight, and it allows for the future possibility of internationalization.
With that in mind, it's good to avoid strongly coupling the display name to the enum constant. Fortunately, there is a class which makes this easy: EnumMap.
public class ApplicationUI {
private final Map<GeneralInformation, String> names;
public ApplicationUI() {
names = new EnumMap<>(GeneralInformation.class);
names.put(GeneralInformation.NAME, "Name");
names.put(GeneralInformation.EDUCATION, "Education");
names.put(GeneralInformation.EMAIL, "Email");
names.put(GeneralInformation.PROFESSION, "Profession");
names.put(GeneralInformation.PHONE, "Phone");
assert names.keySet().containsAll(
EnumSet.allOf(GeneralInformation.class)) :
"Forgot to add one or more GeneralInformation names";
}
public String getNameFor(GeneralInformation info) {
return names.get(info);
}
}
If you are still on Java 1.7 this is what worked for me:
String genInfoValues = "";
boolean firstRun = true;
for (generalInformation info : generalInformation.values()){
if (firstRun) {
firstRun = false;
genInfoValues += info.name();
} else {
genInfoValues += ", " + info.name();
}
}
values() on the enum returns an array. So, it would be simple to do the following to:
System.out.println(Arrays.toString(generalInformation.values()));