I have an enum like that:
public enum Lang {
TR("tr"),
EN("en"),
SE("se");
private String langName;
private Lang(String langName) {
this.langName = langName;
}
}
at another class I want to check whether a langName exists or not. If I put a getter method I can iterate over langNames:
for (Lang langEnum : Lang.values()) {
langEnum.getLangName();
}
However my enum may be too long and I don't want to iterate over an array. I want to use a Map or Set. On the other hand I don't want to another variable within my enum.
How can I check whether my enum has a langName or not?
Well, if every enum constant represents a language (as the code seems to suggest), then I would use an EnumSet.
Set<Lang> langs = EnumSet.allOf(Lang.class);
And then I can check if a language is already there. Like
if(langs.contains(Lang.EN) {
//...
}
Not sure if this is the answer you were looking for. The contains method of EnumSet would not even iterate over the internal collection. The internal collection would be stored in an array and finding an element is calculated based on a hash. So, this in fact, should achieve what you requested in the question.
How about using valueOf?
Lang lang = null;
try {
lang = Lang.valueOf(enumName);
// enum exists
} catch (IllegalArgumentException e) {
// enum does not exist
}
Since your enum name is just the language name capitalized, you can just capitalize the language name and pass it into valueOf.
Related
How can I check if my Input String is in my ArrayList?
I did it like this. But it always shows "not equal". Althoug I insert 1 for example:
public class Main {
public static void main(String[] args) {
String Input = JOptionPane.showInputDialog("Input:");
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
if (Input.equals(list)) {
JOptionPane.showMessageDialog(null, "equals");
} else {
JOptionPane.showMessageDialog(null, "not equal");
}
}
}
If you want to check does List<T> contains T item you should use yourList.contains(T item) in your code, you are using item.equals(object) which is completely different. In short what equals() does is it checks do both objects are stored in the same memory address. Although for some default classes this method is overwritten and works a different way, String class is a good example of that.
Explanation
You wrote
if (Input.equals(list)) { ... }
with Input being a String and list an ArrayList. But, the String#equals (documentation) method compares if two Strings have the same characters (like "hello".equals("hello")), not if the argument list contains the element you called the method on. To quote from its documentation:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
Solution
What you actually want to use is List#contains (documentation):
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that Objects.equals(o, e).
So the code might look like:
if (list.contains(Input)) { ... }
Naming convention
Please note naming conventions. Variable names should always be in camelCase, so input instead of Input. Same for method names.
Only class names are written in PascalCase. And constants (static final) are written in uppercase SNAKE_CASE.
I'm sure this question has allready been answered somewhere, but I' ve searched for half an hour now and I'm running out of keywords, because I have absolutly no idea how to do this.
I have a constructor for a class like this
public MyClass (String name)
{}
what I want is to define Strings so that only those Strings can be entered.
I assume it has something to do with static final strings, but there is quite a lot to be found to those and I dont know how to narrow down the search. Please tell me how that thing I want to do is called, so that I can search for it.
Edit:
Example to what I want:
I want to somehow define a number of Strings. (Or do somethig else that has the same effect, as I said I dont know how to do it)
String one = "ExampleOne";
String two = "ExampleTwo";
so that when I call the constuctor
MyClass myClass = new MyClass("somethingElse");
the constructor wont take it. Or even better eclipse allready showing my what options I have like it does whit "Color. "
Yes you have right you can not override String class because it is final so simply you can create your own StringWrapper class that wraps string.
public class StringWrapper{
private String content;
public StringWrapper(String c){
content = c;
}
//all your methods and fields there, for example delegated methods
public String toString(){
return content.toString();
}
}
But Enum could be also used in your case then you define your Enum values
public enum Color {
WHITE, BLACK, RED, YELLOW, BLUE; //; is required here.
#Override public String toString() {
//only capitalize the first letter
String s = super.toString();
return s.substring(0, 1) + s.substring(1).toLowerCase();
}
}
public myClass (Color color)
{}
There are two ways you can acheive this, either use a enum as constructor parameter. The enum itself contains only the allowed values, which is what I would do, keep everythign nice an oop and you can add logic to enums at a later date.
Or alternatively you can just check if the constuctor paramters value is valid, by performing a comparison and throwing an exception if not in allowed values. Have a predfined list and then, myList.contains(myString) - throw exception if false.
What I want is to define String so that only those Strings can be entered
I think that what you are after are Enums.
Enums will allow you to define a range of values which you can then use. In the example I have linked, the developer can restrict the type of input that he/she will receive to the days of the week.
You can check it in constructor's body at runtime, or if you want to compile-time checks, then you can use enum type argument (enum is a predefined set of constants).
From what I understand it seems like you want to limit what the String can be.
You would do this by putting conditional statements inside the constructor to weed out any Strings you don't want to be entered that would either notify the user that it is an invalid string or throw an exception, and the remainder of the constructor would only be executed in an else statement once it has passed all the tests making sure it is a valid String
I have 3 ints named A, B, and C. These are to be multiplied with the number 52. I have a string that contains the name of which int I want to mulitply (in example below my string type == A;.
I want to know if there is anyway to make the name of the String change into the name of the object/int that I wish to use.
What I have right now:
public class MultiplySomeNumbers{
int A = 100;
int B = 200;
int C = 300;
String type = "A";
final int multiplied = 52;
public int multiply(String type){
return multiplied* ____ //What goes here?
}
}
I DON'T want to do anything like this:
public int multiply(String type){
if(type.equalsIgnoreCase("A"){
return multiplied*A;
}else if(type.equalsIgnoreCase("B"){
...
Any help would be greatly appreciated!
No, that is not possible (maybe with Reflection, but it's still a no-go). Every single situation where you think you might need this does not need it.
There are several issues, but here are a few:
No intellisense for those generated variables
Very unclear code
Ambiguous naming (what if you create a new variable that happens to have the same name as a generated one?)
etc etc etc
You will have to go with your second option.
We might be able to provide a different solution, but the question is rather unclear as it is right now. Perhaps you could expand a little so we can help you better.
Although there may be a way to do this with reflection, it's probably a really bad idea. If you really can't just pass in the value, but want to specify a limited set of constants by which you can multiply, I'd recommend creating an enumerated type.
Taking your same example, but using an enum instead of trying to look up constants by name, would look something like this:
public class MultiplySomeNumbers{
public enum Type {
A(100),
B(200),
C(300);
private final int value;
private Type(int value) {
this.value = value;
}
public final int getValue() {
return value;
}
}
Type type = Type.A;
final int multiplied = 52;
public int multiply(Type type){
return multiplied * type.getValue();
}
}
While there is nothing wrong with using an enum for this solution, it may not be the most flexible solution. Enums are, by design, effectively immutable ... they are intended to have the sense of constants. If you wish to change the value of a variable by multiplying its value by 52, then this is not possible with enums.
What I think you really should do is use a HashMap. A Map is a key / value pair.
The key is the "variable's name"; a String quantity
The value is the "variable's current value"; an Integer quantity (not int!)
Your Map can be declared like this:
Map<String, Integer> myVariables = new HashMap<String, Integer>();
then to load your variables into the map, you simply call the Map's put() method:
myVariables.put("A", Integer.valueOf(100));
myVariables.put("B", Integer.valueOf(200));
myVariables.put("C", Integer.valueOf(300));
Retrieving the value of a variable is as simple as using the get() method with your variable name as the key:
int val = myVariables.get("A").intValue();
Notice that I have chosen to box and unbox the primitive int values myself rather than rely on autoboxing. This is just a personal choice. It does trade off conciseness, but I'd rather see what's actually happening.
In my opinion, using reflection to determine a class field to access dynamically at run time is wholly unsatisfactory and should be avoided ... most especially since using the Java Collections API enables a statically typed, type safe solution that can be checked at compile time.
You can't check for a variable's name. For more information look here, there are some good answers:
Java Reflection: How to get the name of a variable?
But maybe a HashMap can help you, where you store "A", "B", "C" as keys and the respective numbers as value.
edit: Okay, maybe with something like this http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html it could be possible.
My enum is like this currently:
public enum Manufacturers {
Honda,
GM,
Toyota,
Ferrari
}
I need to create a Hashmap so I plan on doing this, is this correct?
Manufacturers mfg = Manufacturers.Honda;
mfg.ordinal() // save as key
i.e. I will store the key using the enumInstance.ordinal()
Also, I need to be able to parse a string which will be the ordinal value of the enumeration, and get an enum back:
Manufacturers mfg = Manufacturers.valueOf(mfgOrdinalValueAsString);
The above gave me an error (the string was "1"). Is this the correct way? I guess I should have a try/catch in there right?
The .valueOf would actually be expecting the String "GM" (for 1).
As for storing your enum values in a map, use EnumMap which is designed specifically for this - and will be fast at it, too.
If you really wanted to reference a value by its ordinal, use something like Manufacturers.values()[1].
A suggestion: better use name() to get the name of the enum as a String, and whenever you need to get back the original Enum from it, use the valueOf() method - since valueOf() expects the name, not the ordinal, as a parameter. For example:
enum Example {ONE, TWO};
String name = Example.ONE.name();
Example e = Example.valueOf(Example.class, name); // e has value ONE
If you definitely need to use the ordinal, the ordinal() method will return an index which you can use to retrieve the respective Enum from the array returned by the values() method. Like this:
int ordinal = Example.ONE.ordinal();
Example e = Example.values()[ordinal]; // e has value ONE
As has already been pointed out, consider using EnumMap, as stated in the documentation, it is
A specialized Map implementation for use with enum type keys. All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient.
EDIT
If you need to associate a different code to each element of the enum (other than its automatically assigned ordinal), you can always add it as an attribute to the enum, together with getters and setters, like this:
public enum Manufacturers {
Honda(10),
GM(20),
Toyota(30),
Ferrari(40);
private int code;
Manufacturers(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
For example:
Manufacturers m = Manufacturers.Honda;
System.out.println(m.getCode()); // prints 10
m.setCode(100);
System.out.println(m.getCode()); // prints 100
Just be aware that you won't be able to reconstruct an Enum object from the code attribute, since that was defined by the programmer.
This question is close, but still not what I want. I'd like to assert in a generic way that two bean objects are equivalent. In case they are not, I'd like a detailed error message explaining the difference instead of a boolean "equal" or "not equal".
import static org.hamcrest.beans.SamePropertyValuesAs.samePropertyValuesAs;
import static org.junit.Assert.assertThat;
#Test
public void beansAreTheSame(){
MyDomianClass bean1 = new MyDomainClass();
MyDomianClass bean2 = new MyDomainClass();
//TODO - some more test logic
assertThat(bean1, samePropertyValuesAs(bean2));
}
I recommend you use unitils library:
http://www.unitils.org/tutorial-reflectionassert.html
public class User {
private long id;
private String first;
private String last;
public User(long id, String first, String last) {
this.id = id;
this.first = first;
this.last = last;
}
}
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
See also:
Is there a Java reflection utility to do a deep comparison of two objects?
NUnit - Assert to check all properties are equal?
You can use Commons Lang's ToStringBuilder to convert both of them into readable strings and then use assertEquals() on both strings.
If you like XML, you can use java.lang.XMLEncoder to turn your bean into XML and then compare the two XML documents.
Personally, I prefer ToStringBuilder since it gives you more control over the formatting and allows you to do things like sorting the elements in a set to avoid false negatives.
I suggest to put each field of the bean in a different line to make it much more simple to compare them (see my blog for details).
You can set all fields like this:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.Matchers.is;
#Test
public void test_returnBean(){
arrange();
MyBean myBean = act();
assertThat(myBean, allOf(hasProperty("id", is(7L)),
hasProperty("name", is("testName1")),
hasProperty("description", is("testDesc1"))));
}
I think, the most generic approach is to reflect the bean members and test them for equality one-by-one. The common lang's EqualsBuilder is a good start and it should be not a big deal, to adapt it (on source level) to your requirements (reporting the differences instead of returning the equals result).
For unit testing this can be done with JUnit and Mockito using ReflectionEquals. When implementing in the following manner, it will dump the JSON representations of the objects when any fields are not equal which makes it easy to find the offending difference.
import static org.junit.Assert.assertThat;
import org.mockito.internal.matchers.apachecommons.ReflectionEquals;
assertThat("Validating field equivalence of objects", expectedObjectValues, new ReflectionEquals(actualObjectValues));
Since you didn't like the answers in the question you referenced, why not just have a toXml method in each bean, turn them into an xml file and then use xmlUnit to compare.
You can get more info on comparing xml files here:
Best way to compare 2 XML documents in Java
You're not really asserting equality, more doing a "diff". Clearly, the meaning of "same" depends upon particular logic for each type, and the representation of the difference also may vary. One major difference between this requirment and a conventional equals() is that usually equals() will stop as soon as the first difference is seen, you will want to carry on and compare every field.
I would look at reusing some of the equals() patterns, but I suspect you'll need to write your own code.
I am assuming here that both beans are of the same type, in which case only the member variable values will differ across bean instances.
Define an util class (public static final with private ctor) called, say, BeanAssertEquals. Use Java reflection to obtain the value of each member variable in each bean. Then do an equals() between values for the same member variable in different beans. If an equality fails, mention the field name.
Note: member variables are usually private, so you would need to use reflection to temporarily change the accessibility of private members.
Additionally, depending how fine-grained you want the assertion to work, you should consider the following:
Equality of member variables not in the bean class but all superclasses.
Equality of elements in arrays, in case a member variable is of type array.
For two values of a given member across beans, you might consider doing BeanAssertEquals.assertEquals(value1, value2) instead of value1.equals(value2).
(to build on my comment to Andreas_D above)
/** Asserts two objects are equals using a reflective equals.
*
* #param message The message to display.
* #param expected The expected result.
* #param actual The actual result
*/
public static void assertReflectiveEquals(final String message,
final Object expected, final Object actual) {
if (!EqualsBuilder.reflectionEquals(expected, actual)) {
assertEquals(message,
reflectionToString(expected, ToStringStyle.SHORT_PREFIX_STYLE),
reflectionToString(actual, ToStringStyle.SHORT_PREFIX_STYLE));
fail(message + "expected: <" + expected + "> actual: <" + actual + ">");
}
}
This is what I use, and I believe it meets all basic requirements. By doing the assert on the reflective ToString then Eclipse will highlight the difference.
While Hamcrest can offer a much nicer message, this does involve a good deal less code.
The first quesion I'd have to ask if is, do you want to do 'deep' equals on the Bean? does it have child beans that need to be tested? You can override the equals method, but this only returns a boolean, so you could create a 'comparator' and that could throw an exception with a message about what was not equal.
In the following examples, I've listed a few ways to implement the equals method.
if you want to check if they are the same object instance, then the normal equals method from Object will tell you.
objectA.equals(objectB);
if you want to write a customer equals method to check that all the member varibles of an object make them equal then you can override the equals method like this...
/**
* Method to check the following...
* <br>
* <ul>
* <li>getTitle</li>
* <li>getInitials</li>
* <li>getForename</li>
* <li>getSurname</li>
* <li>getSurnamePrefix</li>
* </ul>
*
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(Object obj)
{
if ( (!compare(((ICustomer) obj).getTitle(), this.getTitle()))
|| (!compare(((ICustomer) obj).getInitials(), this.getInitials()))
|| (!compare(((ICustomer) obj).getForename(), this.getForename()))
|| (!compare(((ICustomer) obj).getSurname(), this.getSurname()))
|| (!compare(((ICustomer) obj).getSurnamePrefix(), this.getSurnamePrefix()))
|| (!compare(((ICustomer) obj).getSalutation(), this.getSalutation())) ){
return false;
}
return true;
}
The last option is to use java reflection to check all the member varibles in the equals method. This is great if you really want to check every member varible via its bean get/set method. It wont (I dont think) allow you to check private memeber varibles when testing of the two objects are the same. (not if your object model has a circular dependancy, dont do this, it will never return)
NOTE: this is not my code, it comes from...
Java Reflection equals
public static boolean equals(Object bean1, Object bean2)
{
// Handle the trivial cases
if (bean1 == bean2)
return true;
if (bean1 == null)
return false;
if (bean2 == null)
return false;
// Get the class of one of the parameters
Class clazz = bean1.getClass();
// Make sure bean1 and bean2 are the same class
if (!clazz.equals(bean2.getClass()))
{
return false;
}
// Iterate through each field looking for differences
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++)
{
// setAccessible is great (encapsulation
// purists will disagree), setting to true
// allows reflection to have access to
// private members.
fields[i].setAccessible(true);
try
{
Object value1 = fields[i].get(bean1);
Object value2 = fields[i].get(bean2);
if ((value1 == null && value2 != null) ||
(value1 != null && value2 == null))
{
return false;
}
if (value1 != null &&
value2 != null &&
!value1.equals(value2))
{
return false;
}
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
return true;
The one thing that this does not do it to tell you the reason for the difference, but that could be done via message to Log4J when you find a section that is not equal.
The xtendbeans library could be of interest in this context:
AssertBeans.assertEqualBeans(expectedBean, actualBean);
This produces a JUnit ComparisonFailure à la:
expected:
new Person => [
firstName = 'Homer'
lastName = 'Simpson'
address = new Address => [
street = '742 Evergreen Terrace'
city = 'SpringField'
]
]
but was:
new Person => [
firstName = 'Marge'
lastName = 'Simpson'
address = new Address => [
street = '742 Evergreen Terrace Road'
city = 'SpringField'
]
]
You could also use it just to get the textual representation for other purposes:
String beanAsLiteralText = new XtendBeanGenerator().getExpression(yourBean)
With this library you can use the above syntactically valid object initialization code fragment to copy/paste it into a (Xtend) source class for the expectedBean, but you don't not have to, it can perfectly well be used without Xtend as well.