This question already has answers here:
Compare two objects with a check for null
(7 answers)
Closed 5 years ago.
I have to compare two Boolean wrappers with each other. As a result I want to know if they are equal or not.
This is what I came up with:
public static boolean areEqual(final Boolean a, final Boolean b) {
if (a == b) {
return true;
}
if (a != null && b != null) {
return a.booleanValue() == b.booleanValue();
}
return false;
}
Is there a better and/or shorter way to correctly compare two Boolean wrappers for equality?
First I wanted to use Object.equals() or Boolean.compareTo() but both ways could end up in a NullPointerException, right?
Maybe there is something that I don't see here, that's why I'm asking.
The shortest you can get, with null safety (works naturally for any other objects that implement equals()):
java.util.Objects.equals(a, b);
There is no need for you to reinvent the wheel.
If you are using Java 7 or later, use the java.util.Objects class (as mentioned by Kayaman).
If you are using an earlier version of java, use the Apache BooleanUtils class.
Try a google search for "apache booleanutils" to find out how to get it.
Edit: corrected java version.
It is working for me.
public class MyClass {
public static void main(String args[]) {
Boolean x=true;
Boolean y=true;
System.out.println(compare(x,y)); // true
x=false;
y=true;
System.out.println(compare(x,y)); // false
x=true;
y=false;
System.out.println(compare(x,y)); // false
x=false;
y=false;
System.out.println(compare(x,y)); // true
x=null;
y=null;
System.out.println(compare(x,y)); // true
}
public static boolean compare(final Boolean a, final Boolean b) {
if (a == null || b == null) {
return a == b;
}
return a.equals(b);
}
}
Probe with https://www.jdoodle.com/online-java-compiler
Edit: add exception to null values.
Related
I have two arrayLists<myObject>, where myObject is an object of a custom class I've created. I want to be able to compare those arrayLists using the equals() method.
After reading and looking for answers, I've read that certain objects like int[] are only considered equal by the equals() method when they are referencing the same thing.
To fix that, I tried to override the equals method in my custom object. My objects have 3 atributes (all basic types), so my equals method now returns true if all the 3 atributes are equal to those of the object compared, and false otherwise. However, comparing the arraylists still doesn't work. What am I doing wrong?
Excuse me for explaining the code instead of posting it, I do it because the variables and names aren't in English.
EDIT: Ok, here's the code. Compra is my custom class; cantidad,concepto and id are its atributes.
#Override
public boolean equals(Object obj) {
boolean result = true;
if (obj == null) {
result = false;
}else{
Compra comprobada = (Compra) obj;
if(!(this.id == comprobada.getId())){
result = false;
}
if(!(this.cantidad == comprobada.getCantidad())){
result = false;
} if(!this.concepto.equals(comprobada.getConcepto())){
result = false;
}
}
return result;
}
Based on this one :
How can I check if two ArrayList differ, I don't care what's changed
If you have implemented your custom object equals correct (you actually override it and have your one) and the size of the arrayList is the same and each of the pair of the objects is equal then it will return equal. In other words what you are trying to do is totally correct but your arrayLists are not actually having exactly the equal objects in exact order.
Make sure that your equal is called when you check for collection equality by doing a System.out.println() to investigate what is going on.
If you don't mind please send the equals of your object.
I run your code in an isolated example and works fine (outtputs true) - I improved the equals method so it doesn't do so many if checks as if only one of them is not equal it should return false.
class stackoverflow {
public static void main(String args[]){
ArrayList<Compra> array1 = new ArrayList<>();
ArrayList<Compra> array2 = new ArrayList<>();
array1.add(new Compra(1,2,"test"));
array2.add(new Compra(1,2,"test"));
System.out.println(array1.equals(array2));
}
}
class Compra {
int id;
int cantidad;
String concepto;
public Compra(int id, int cantidad, String concepto){
this.id = id;
this.cantidad = cantidad;
this.concepto = concepto;
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}else{
Compra comprobada = (Compra) obj;
if(!(this.id == comprobada.getId())){
return false;
}
if(!(this.cantidad == comprobada.getCantidad())){
return false;
}
if(!this.concepto.equals(comprobada.getConcepto())){
return false;
}
}
return true;
}
public int getId() {
return id;
}
public int getCantidad() {
return cantidad;
}
public String getConcepto() {
return concepto;
}
}
Some things to check:
Are you sure you don't change the order of the things in ArrayList??:
Do you print to make sure that these equals checks happen and return true or false as expected?
Are you sure that concepto Strings are exactly the same, with the same case and don't contain extra spaces etc?
As you haven't posted code i suggest you to check into Comparable class and method compareTo and how to use it for custom classes.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I'm writing some codes that test if there is "xx" in a string. For instance, doubleX("aaxxbb") should return true, and doubleX("axabb") should return false.
Here is my code:
private static boolean doubleX(String str) {
for(int i=0;i<str.length()-1;i++){
System.out.println(str.substring(i,i+2));
if(str.substring(i,i+2) == "xx") return true;
}
return false;
}
Why does doubleX("aaxxbb") return false?
You have to use .equals instead of ==. For more information, follow the duplication message.
return str.contains("xx");
Is a lot clearer though.
You should understand the difference between == and equals: the first one compares references, the second compares actual values.
Your code is wildly inefficient.
I'd try something like this:
private static boolean doubleX(String str) {
return (str.indexOf("xx") != -1);
}
Use equals() for checking the content of a String to another rather than ==. == checks for reference equality.
private static boolean doubleX(String str) {
for(int i=0;i<str.length()-1;i++){
System.out.println(str.substring(i,i+2));
if(str.substring(i,i+2).equals("xx")) return true;
}
return false;
}
Even you can directly code like:
private static boolean doubleX(String str) {
return str.contains("xx");
}
Spring Expression Language (SpEL) in Spring Security to compare object use equals() or ==?
For example(method equals () is not called!):
class SecurityObject {
public boolean equals(Object obj) {
//...
}
}
#PreAuthorize(" #secObject == #otherSecObject ")
public void securityMethod(SecurityObject secObject, SecurityObject otherSecObject) {
//...
}
This is normal!? I need to use #PreAuthorize(" #secObject.equals(#otherSecObject) ") everywhere?
UPDATE
Why in first case Spring Security calling .equals(), and the second not?
//TestObject
public class TestObject {
private static final Logger log = LoggerFactory.getLogger(TestObject.class);
private Long id;
public TestObject(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Objects.hashCode(this.id);
return hash;
}
#Override
public boolean equals(Object obj) {
log.info("equals");
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TestObject other = (TestObject) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
}
//TestService
#PreAuthorize(" #one == #two ")
public String testEqualsInAnnotation(Long one, Long two) {
//...
}
#Override
#PreAuthorize(" #one == #two ")
public String testEqualsInAnnotation(TestObject one, TestObject two) {
//...
}
//Test
log.info("for Long");
Long one = new Long(500);
Long two = new Long(500);
log.info("one == two: {}", (one==two)? true : false); // print false
log.info("one equals two: {}", (one.equals(two))? true : false); // print true
testService.testEqualsInAnnotation(one, two); //OK
log.info("for TestObject");
TestObject oneObj = new TestObject(new Long(500));
TestObject twoObj = new TestObject(new Long(500));
log.info("oneObj == twoObj: {}", (oneObj==twoObj)? true : false); // print false
log.info("oneObj equals twoObj: {}", (oneObj.equals(twoObj))? true : false); // print true
testService.testEqualsInAnnotation(oneObj, twoObj); // AccessDeniedException: Access is denied
UPDATE 2
equals() never invoked at all
package org.springframework.expression.spel.ast;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.support.BooleanTypedValue;
/**
* Implements equality operator.
*
* #author Andy Clement
* #since 3.0
*/
public class OpEQ extends Operator {
public OpEQ(int pos, SpelNodeImpl... operands) {
super("==", pos, operands);
}
#Override
public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state).getValue();
Object right = getRightOperand().getValueInternal(state).getValue();
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
if (op1 instanceof Double || op2 instanceof Double) {
return BooleanTypedValue.forValue(op1.doubleValue() == op2.doubleValue());
} else if (op1 instanceof Long || op2 instanceof Long) {
return BooleanTypedValue.forValue(op1.longValue() == op2.longValue());
} else {
return BooleanTypedValue.forValue(op1.intValue() == op2.intValue());
}
}
if (left!=null && (left instanceof Comparable)) {
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) == 0);
} else {
return BooleanTypedValue.forValue(left==right);
}
}
}
As per spEL documentation, You need to create ExpressionParser instance, create an Expression instance and get the value like below
String name = "Nikola Tesla";
Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(Boolean.class);
result evaluates to 'true'. That says when we need to compare any two objects, then we need to override the equals() method and pass the two objects in to parser#parseExpression("obj1 == obj2") and then call the exp#getValue(Boolean.class) to evaluate. In the similar way, the Expression instance can also have expression string containing Obj1.equals(Obj2) for checking the equality. so, both the ways of checking equality are possible with spEL.
You may have discovered this already, since it is in the OpEq code in 'Update 2' of the original post, but...
The comparison operators lt < gt > le <= ge >= eq == ne != are based on java's Comparable interface.
So, if you've got a custom type that you want to be able to compare using == or != in SpEL expressions, then you could write it to implement Comparable.
Of course, then you'll have to figure out some sane rule to decide which object is before the other when they're not equivalent.
That said, I can't find anything in Spring's current documentation indicating this.
rdm, I think you have to use permission evaluator to evaluate the expressions. I don't think you have really injected/passed values for the objects in the following expression.
#Override
#PreAuthorize(" #one == #two ")
public String testEqualsInAnnotation(TestObject one, TestObject two) {
//...
I tried to do the same thing, but I failed to pass values, hence couldn't able to evaluate the expressions. My suggestion is to implement your custom permission evaluator for the above expression, and inject/pass values from the evaluator. To generalize my idea, my suspect is the objects are null, that is why you couldn't able to evaluate it. Please let us know if you can really pass values of the objects inside here : #PreAuthorize(" #one == #two ")
Added:
I am using permission evaluator to evaluate expressions under #PreAuthorize(...) annotation. Because I couldn't able to pass values to the parameters as I explained above. If it is possible to pass/inject values, it will be good to reduce complexity that can come from using permission evaluator.
rdm or others, can you point me how to pass the values for the parameters under #PreAuthorize(...) if possible?
Sorry for asking another question on rdm's post, and thank you in advance for your help!.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I seem to be having a problem with a boolean test. when I use this code:
public boolean setPkg (String inPkg)
{
boolean isValid;
if ((inPkg.toUpperCase() != "A" ) || (inPkg.toUpperCase() != "B" ) || (inPkg.toUpperCase() != "C"))
isValid = false;
else
{
pkg = inPkg;
isValid = true;
}
return isValid;
}
It returns false on "A". However when I only test for "A":
...
if (inPkg.toUpperCase() != "A" )
isValid = false;
else
{
pkg = inPkg;
isValid = true;
}
return isValid;
...
it returns true.
what am I missing?
I have also tried to use multiple if else statements to test for A, B, or C and i get false for A. B and C dont get tested as an exception of my making is getting thrown.
Two things over here :
replace != with equals method for comparison
replace || with &&
Always use oneString.equals(otherString), not oneString == otherString, when comparing strings.
For example, instead of:
(inPkg.toUpperCase() != "A" )
use this instead:
(!(inPkg.toUpperCase().equals("A")))
NEVER compare strings with == or !=. See: How do I compare strings in Java?
The issue is that you're using == to compare strings. This doesn't do what you think it does (it compares string references, not the character sequences).
Use s1.equals(s2) instead, as in
!inPkg.toUpperCase().equals("A")
etc.
See Java comparison with == of two strings is false?
== and != compares the Object references. they are not equal as they are not the same object.
String.equals(otherString) compares the content of the String. You want to use this function.
Is there a better way to negate a boolean in Java than a simple if-else?
if (theBoolean) {
theBoolean = false;
} else {
theBoolean = true;
}
theBoolean = !theBoolean;
theBoolean ^= true;
Fewer keystrokes if your variable is longer than four letters
Edit: code tends to return useful results when used as Google search terms. The code above doesn't. For those who need it, it's bitwise XOR as described here.
There are several
The "obvious" way (for most people)
theBoolean = !theBoolean;
The "shortest" way (most of the time)
theBoolean ^= true;
The "most visual" way (most uncertainly)
theBoolean = theBoolean ? false : true;
Extra: Toggle and use in a method call
theMethod( theBoolean ^= true );
Since the assignment operator always returns what has been assigned, this will toggle the value via the bitwise operator, and then return the newly assigned value to be used in the method call.
This answer came up when searching for "java invert boolean function". The example below will prevent certain static analysis tools from failing builds due to branching logic. This is useful if you need to invert a boolean and haven't built out comprehensive unit tests ;)
Boolean.valueOf(aBool).equals(false)
or alternatively:
Boolean.FALSE.equals(aBool)
or
Boolean.FALSE::equals
If you use Boolean NULL values and consider them false, try this:
static public boolean toggle(Boolean aBoolean) {
if (aBoolean == null) return true;
else return !aBoolean;
}
If you are not handing Boolean NULL values, try this:
static public boolean toggle(boolean aBoolean) {
return !aBoolean;
}
These are the cleanest because they show the intent in the method signature, are easier to read compared to the ! operator, and can be easily debugged.
Usage
boolean bTrue = true
boolean bFalse = false
boolean bNull = null
toggle(bTrue) // == false
toggle(bFalse) // == true
toggle(bNull) // == true
Of course, if you use Groovy or a language that allows extension methods, you can register an extension and simply do:
Boolean b = false
b = b.toggle() // == true
The class BooleanUtils supportes the negation of a boolean. You find this class in commons-lang:commons-lang
BooleanUtils.negate(theBoolean)
Boolean original = null; // = Boolean.FALSE; // = Boolean.TRUE;
Boolean inverse = original == null ? null : !original;
If you're not doing anything particularly professional you can always use a Util class. Ex, a util class from a project for a class.
public class Util {
public Util() {}
public boolean flip(boolean bool) { return !bool; }
public void sop(String str) { System.out.println(str); }
}
then just create a Util object
Util u = new Util();
and have something for the return System.out.println( u.flip(bool) );
If you're gonna end up using the same thing over and over, use a method, and especially if it's across projects, make a Util class. Dunno what the industry standard is however. (Experienced programmers feel free to correct me)
Before:
boolean result = isresult();
if (result) {
result = false;
} else {
result = true;
}
After:
boolean result = isresult();
result ^= true;