I want to add second argument to when() condition for ObservableBooleanValue. In case when there is only one argument
it`s working correctly. Problem in that line:
game.winnerProperty().isEqualTo(Square.State.EMPTY) || (GameTimer::isTimeOver==true)
This is ok:
game.winnerProperty().isEqualTo(Square.State.EMPTY) //This is BooleanBinding
Code:
playerLabel.textProperty().bind(
Bindings.when(
game.gameOverProperty().not()
)
.then("Actual Player: ")
.otherwise(
Bindings.when(
game.winnerProperty().isEqualTo(Square.State.EMPTY) || (GameTimer::isTimeOver==true)
)
.then("Draw")
.otherwise("Winner: ")
)
);
How to add second argument which type is boolean?
Sometimes it's convenient to combine multiple bindings.
However this can lead to complex code that is hard to understand/maintain. It would be easier to use Bindings.createStringBinding and add the proper dependencies:
playerLabel.textProperty().bind(
Bindings.createStringBinding(() -> {
if (game.isGameOver()) {
return Square.State.EMPTY.equals(game.getWinner()) || gameTimer.isTimeOver()
? "Draw"
: "Winner: ";
} else {
return "Actual Player: ";
}
},
game.gameOverProperty(),
game.winnerProperty(),
gameTimer.timeOverProperty()));
You can do
game.winnerProperty().isEqualTo(Square.State.EMPTY).or(/* whatever you actually mean here */);
The argument to or here needs to be another ObservableBooleanValue (e.g. a BooleanProperty): I don't really know what is intended by the method reference you currently have.
Related
Currently, I have the following code that works:
//in class Bar
public Foo getFooIfItIsPresent(String param) {
Optional<Foo> result = loadOptionalFoo(param);
if (result.isPresent()) {
return result.get();
} else {
return null;
}
// main driver code
Foo foo = Bar.getFooIfItIsPresent(param);
if (foo != null) {
// Currently just print, but might want to do stuff like pass foo to another object, etc.
System.out.println(foo.getSomething() + foo.getSomethingElse());
}
This is kind of ugly, because I am checking for null explicitly; in addition, I have a convoluted function getFooIfItIsPresent that exists for the sole purpose of the isPresent() dance. I would want to do something like:
Bar.loadOptionalFoo(param).ifPresent((foo) -> {
// Print, or whatever I wanna do!
System.out.println(foo.getSomething() + foo.getSomethingElse());
});
I know this doesn't compile. There's been a very similar question, and I've tried a bunch of stuff, but the compiler complains. Eg:
Bar.loadOptionalFoo(week).map(foo -> {
// Print, or whatever I wanna do!
System.out.println(foo.getSomething() + foo.getSomethingElse());
}).filter(Objects::nonNull);
Yes, the code above is nonsensical, but I can't seem to wrap my head around getting an elegant solution for this, so a bit of help would be much appreciated!
tl;dr
The code you showed saying “I know this doesn't compile” actually should compile. That code is your solution.
Using similar code, see this method:
public Optional < DayOfWeek > getFavoriteDayOfWeek ( )
{
return Optional.ofNullable( DayOfWeek.WEDNESDAY ); // Silly implementation for demonstration.
}
…called like this:
this.getFavoriteDayOfWeek().ifPresent(
( DayOfWeek dow ) -> { … dow.get() … }
);
…run live successfully at IdeOne.com.
Keep in mind that an Optional is its own object, wrapping some other object as its payload. So be careful about your type declarations: Optional<DayOfWeek> someVar versus DayOfWeek someVar.
Return the Optional
If a null is an acceptable value in your domain, then return the Optional. Returning a null unwrapped from within an Optional defeats the purpose of an Optional.
The purpose of an Optional is to signal to the calling method that a null is indeed a valid possibility. The type system of Java is being used to remind the calling programmer to code for the possibility of a null. An Optional object is like a big safety-orange traffic sign saying: “Beware: possible NULL ahead”.
Returning just null unwrapped from within an Optional adds no value, and makes for brittle code.
The code shown in the Question is jumping through extra hoops needlessly, just introducing an extra level of indirection with no benefit. The calling method should indeed receive an Optional if a payload of null is a valid result.
So this:
//in class Bar
public Foo getFooIfItIsPresent(String param) {
Optional<Foo> result = loadOptionalFoo(param);
if (result.isPresent()) {
return result.get();
} else {
return null;
}
// main driver code
Foo foo = Bar.getFooIfItIsPresent(param);
if (foo != null) {
// Currently just print, but might want to do stuff like pass foo to another object, etc.
System.out.println(foo.getSomething() + foo.getSomethingElse());
}
…should be:
//in class Bar
// ➥ Delete this method `getFooIfItIsPresent`. Adds no value.
// public Foo getFooIfItIsPresent(String param)
…and…
// main driver code
Optional<Foo> result = someBar.loadOptionalFoo( param );
if ( result.isPresent() ) {
// Currently just print, but might want to do stuff like pass foo to another object, etc.
Foo foo = result.get() ; // Calling `get` is safe because we checked for null in the `if … isPresent` line above.
System.out.println( foo.getSomething() + foo.getSomethingElse() ) ;
}
Notice how we call Optional::get only after checking for null by calling Optional::ifPresent.
The Optional class offers various methods if you want to address the if else condition where the Optional is empty with no Foo object present. See methods such as orElse, orElseGet, and orElseThrow.
Your problematic code should indeed compile
You said this code does not compile:
Bar.loadOptionalFoo(param).ifPresent((foo) -> {
// Print, or whatever I wanna do!
System.out.println(foo.getSomething() + foo.getSomethingElse());
});
Actually, that code should compile. It is perfectly reasonable to do, another variation of what I showed as a solution above.
Here is a similar example. I make the method getFavoriteDayOfWeek which returns an Optional< DayOfWeek > using the DayOfWeek enum class built into Java. If a favorite day is registered, the method returns an Optional holding a DayOfWeek object. If no favorite has yet been determined, the method returns an empty Optional. Here is our dummy version of that method.
public Optional < DayOfWeek > getFavoriteDayOfWeek ( )
{
return Optional.ofNullable( DayOfWeek.WEDNESDAY );
}
Calling that method using code similar to your code:
this.getFavoriteDayOfWeek().ifPresent(
( DayOfWeek dayOfWeek ) -> {
// Print, or whatever I wanna do!
System.out.println( dayOfWeek.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) );
}
);
When run:
mercredi
INFO - Done running demo.
You can change the WEDNESDAY object with null to experiment.
public Optional < DayOfWeek > getFavoriteDayOfWeek ( )
{
return Optional.ofNullable( null );
}
When run, we see that the System.out.println( dayOfWeek.getDisplayName(… code is never called because the conditional test for our Optional<DayOfWeek> actually containing a DayOfWeek object (ifPresent) was not met. We see output only from our second System.out.println, for "Done running".
INFO - Done running demo.
See this code run live at IdeOne.com.
Making an Optional
The body of your Question seems to be asking about extracting a value from an Optional. I showed that above.
The title of your Question seems to be about wrapping a value in an Optional.
If you know you want to return a null, return Optional.empty().
If returning something that may or may not be null, return Optional.ofNullable( x ).
If returning something that should definitely not be null in that situation, return Optional.of( x ). That method throws NullPointerException if the value is null. Use this method when the presence of a null means something went very wrong with your app.
A tip, by the way, after seeing your use of if (foo != null) {:
If you do need to test for a null, I suggest instead of using x != null or x == null that you instead use the Objects class methods, Objects.nonNull( Object obj ) and Objects.isNull( Object obj ), respectively.
Even better, in a situation where the presence of a null in intolerable, meaning a major unexpected failure in your code, call Objects.requireNonNull( T obj ). This method throws NullPointerException if receiving a null. Even better, this method returns the object passed. This makes it perfect for assigning passed arguments to other variables.
public void doSomething( final Fruit fruit , final DayOfWeek dayOfWeek )
{
this.fruit = Objects.requireNonNull( fruit ) ;
this.dayOfWeek = Objects.requireNonNull( dayOfWeek ) ;
}
Last tip: Java 14 brings more helpful NullPointerException objects, better pinpointing the place of failure. See JEP 358: Helpful NullPointerExceptions.
I fails to understand your problem with ifPresent since you are not even handling the case where the value is empty: why not use a method reference?
Have some method take a Foo parameter and do whatever:
class X {
private Optional<Foo> loadFoo(String name) {...}
private void consumeFoo(Foo foo) {...}
void doSomething(String name) {
this.loadFoo(name).ifPresent(this::consumeFoo);
}
}
Also you can do
return result.orElse(null);
Instead of:
if (result.isPresent()) {
return result.get();
} else {
return null;
}
I agree with Basil, but here's another possibility :
Bar.loadOptionalFoo(week)
.map(foo ->
String.format("%s %s",
foo.getSomething(),
foo.getSomethingElse()))
.ifPresent(System.out::println);
You can directly return null more elegantly, then have that null check :). Or if you don't want to have null check, than you can return Optional and do isPresent check
public Foo getFoo(String param) {
return Optional.ofNullable(loadOptionalFoo(param)).orElse(null);
}
Foo foo = Bar.getFoo(param);
if (foo != null) {
// Currently just print, but might want to do stuff like pass foo to another object, etc.
System.out.println(foo.getSomething() + foo.getSomethingElse());
}
One area that I often finding confusing with java 8 streams is when an intermediate result can be empty, and you need to take alternate paths if it's empty or not empty.
For instance, if I have code like this:
String pymtRef = defaultValue;
Optional<PaymentTender> paymentTender = paymentTenders.stream()
.filter(pt -> (pt.getFlag() == Flag.N || pt.getFlag() == null)).findFirst();
if (paymentTender.isPresent()) {
pymtRef = paymentTender.get().getId();
}
return pymtRef;
I would like to figure out how to remove the conditional block and do this in a single stream.
If I simply call ".map" on the filter result, that can work if it found a matching entry. If not, I get a NoSuchElementException.
I might instead use "ifPresent()", but the return type of that is "void".
Is there any way to make this cleaner?
Update:
The solution using "orElse()" works fine.
The entire method now looks something like this:
public String getPaymentReference(OrderContext orderContext) {
List<PaymentTender> paymentTenders = getPaymentTenders(orderContext);
if (paymentTenders.size() == 1) {
return paymentTenders.get(0).getId();
}
return paymentTenders.stream()
.filter(pt -> (pt.getAutoBill() == AutoBill.N || pt.getAutoBill() == null))
.findFirst().map(pt -> pt.getId()).orElse(DEFAULT_VALUE);
}
Can you think of a way to include the first conditional in the stream without making it more complex?
Calling get() straight after map will yield an exception if the Optional has an empty state, instead call orElse after map and provide a default value:
paymentTenders.stream()
.filter(pt -> (pt.getFlag() == Flag.N || pt.getFlag() == null))
.findFirst()
.map(PaymentTender::getId)
.orElse(someDefaultValue);
Edit:
As for:
Can you think of a way to include the first conditional in the stream
without making it more complex?
No, this is better the way you've done it. it's more readable and easier to follow.
introducing any type of logic to make it into one pipeline (if possible) will just end of being complex and hence harder to follow and understand.
You can do it in one statement via
public String getPaymentReference(OrderContext orderContext) {
List<PaymentTender> paymentTenders = getPaymentTenders(orderContext);
return paymentTenders.stream()
.filter(paymentTenders.size() == 1? pt -> true:
pt -> pt.getAutoBill() == AutoBill.N || pt.getAutoBill() == null)
.findFirst().map(PaymentTender::getId).orElse(DEFAULT_VALUE);
}
Note that this will not repeat the evaluation of the paymentTenders.size() == 1 for every element, but use a different function, depending on the state. When the condition is fulfilled, pt -> true will accept any element, which will result in the sole element being accepted as intended. Otherwise, the ordinary predicate, pt -> pt.getAutoBill() == AutoBill.N || pt.getAutoBill() == null is used.
I have my custom SonarQube plugIn up and running on a local SonarQube server and it works fine. Now I want to add more stuff to it. I'm interested in coding my own Sonar Rule which checks if the non deprecated constructor is used for one class.
Possible constructor calls:
#Deprecated
public ExampleClass(String a)
{
//deprecated/old/wrong stuff happening
}
public ExampleClass(String a, String b)
{
//correct stuff happening
}
I'm already at the state, that only Method notes will be visited.
Now I'm wondering how can I check which new ExampleClass expression is used?
Found a working solution.
Here's what I did:
set nodesToVisit to Tree.Kind.ASSIGNMENT
check if the expression is Tree.Kind.NEW_CLASS
check if identifier is ExampleClass.class.getSimpleName()
do my argument checks
Code:
AssignmentExpressionTree assignment = (AssignmentExpressionTree) tree;
if ( assignment.expression().is(Tree.Kind.NEW_CLASS) )
{
NewClassTreeImpl expression = (NewClassTreeImpl) assignment.expression();
IdentifierTreeImpl identifier = (IdentifierTreeImpl) expression.identifier();
if ( StringUtils.equals(identifier.name(), ExampleClass.class.getSimpleName()) )
{
ArgumentListTreeImpl arguments = (ArgumentListTreeImpl) expression.arguments();
if ( arguments.size() != 2 )
{
reportIssue(expression, "Use the 2 parameter constructor call when creating new ExampleClass objects!");
}
else if ( StringUtils.indexOfAny(arguments.get(1).symbolType().name(), POSSIBLE_PARAMETER_TYPES) == -1 )
{
reportIssue(expression, "The second parameter must be from type String");
}
}
}
If you find any improvement of my rule, please let me know. Thanks!
How do I go about evaluating logical expression like "VERB1 OR (VERB2 AND VERB3) OR (VERB4)" entered at runtime. VERB* are placeholder to evaluate certain conditions. For example, VERB1 might mean check for the existence of a record in database.
In expression "VERB1 OR (VERB2 AND VERB3) OR (VERB4)", other verbs should not be executed if VERB1 is true
EDIT: Example described at http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/ seems very similar to what I am trying to do. However, the optimization step (other verbs should not be executed if VERB1 is true) doesn't seem to be there.
If you can use || and && in place of AND and OR, you can just use groovy's missing property methods and the GroovyShell base class setting like so:
import org.codehaus.groovy.control.CompilerConfiguration
// The command to be executes
def command = "VERB1 || (VERB2 && VERB3) || (VERB4)"
// Set a base class for the GroovyShell
new CompilerConfiguration().with { compiler ->
compiler.scriptBaseClass = 'VerbHandlingBaseClass'
new GroovyShell( this.class.classLoader, new Binding(), compiler ).with { shell ->
// and evaluate the command
shell.evaluate( command )
}
}
abstract class VerbHandlingBaseClass extends Script {
boolean VERB1() {
System.out.println( 'CHECK THE DATABASE, RETURN FALSE' )
false
}
boolean VERB2() {
System.out.println( 'WRITE A LOG ENTRY RETURN TRUE' )
true
}
boolean VERB3() {
System.out.println( 'VALIDATE SOMETHING, RETURN TRUE' )
true
}
boolean VERB4() {
System.out.println( 'THIS WONT BE REACHED, AS VERB2 && VERB3 == true' )
true
}
def propertyMissing( String name ) {
"$name"()
}
}
That should print:
CHECK THE DATABASE, RETURN FALSE
WRITE A LOG ENTRY RETURN TRUE
VALIDATE SOMETHING, RETURN TRUE
You mentioned ANTLR in your tags: have you given this a go? You can create a full boolean grammar in ANTLR but it gets much harder when you get down to the level of how to evaluate the verbs.
If there is a small, fixed set of verbs which may be queried you can easily create a mapping between the verbs and the functions.
If there is a larger list of verbs, you may be able to use reflection to call specific methods to evaluate them.
If your verbs can include mathematical comparisons, this all gets a bit harder as you create a mathematical lexer and parser as well.
Without a more specific question and knowledge of what you have tried in ANTLR I'm not sure I can give you much more advice.
EDIT: Based on your comments, I'll add some more.
You can add parsing rules to your grammar:
boolean_or returns [boolean b]
: b1=boolean_and {$b = $b1.b;}
(OR b2=boolean_and {$b = $b || $b2.b;})*
;
boolean_atom returns [boolean b]
:
((numeric_comparison)=> b1=numeric_comparison {$b = $b1.b;}
| TRUE {$b = true;} | FALSE {$b = false;}
| s1=VERB {$b = evalVerb($s1.s);}
| LPAREN b1=boolean_expr RPAREN {$b = $b1.b;}
)
;
Thats a small part of a boolean parser I'm currently using. You can fill in the blanks.
And then call the parser using something like
ANTLRStringStream in = new ANTLRStringStream(booleanString);
ActionLexer lexer = new ActionLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
BooleanParser parser = new BooleanParser(tokens);
try {
return parser.eval();
} catch (Exception e) {
}
This doesn't account for your requirement of returning early, but I'm sure you can figure out how to do that.
This might not be the best way to do things, but its the way that I've gotten it to work for me in the past. Hope this helps.
Hey, long time listener first time caller, and I'm asking a question related to Java reflection, and how easy it lends itself to apparently ugly coding. The following method attempts to take two similar objects (one object having all of the fields of the other object, and then some) and compare the two of them for equality. It will (allegedly) return true if the getters that the objects share are equal, and will return false if they are not equal.
public boolean validateArchive( Object record, Object arcRecord ) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
log.debug( record.getClass().toString() );
Object methodValue;
Object arcMethodValue;
for ( Method method : record.getClass().getMethods() )
{
if ( method.getTypeParameters().length == 0 && method.getName().startsWith( "get" ) && !method.getName().startsWith( "getClass" ) )
{
methodValue = method.invoke( record );
arcMethodValue = arcRecord.getClass().getMethod( method.getName() ).invoke( arcRecord );
log.debug( "Method name: " + method.getName() );
log.debug( "Archive value: " + arcMethodValue );
log.debug( "Object value: " + methodValue );
if ( arcMethodValue != null && methodValue != null && !arcMethodValue.equals( methodValue ) )
{
return false;
}
else
{
if ( arcMethodValue == null && methodValue != null || methodValue == null && arcMethodValue != null )
{
return false;
}
}
}
}
return true;
}
This method does what I expect it to do in the unit tests, but it looks ugly, and feels wrong (I'm particularly not a fan of the nested 'if'). I was just hoping for some pointers on how to do this more effectively/efficiently. If I've broken some kind of posting rule, feel free to correct me, I am eager to learn, etc.
For this particular task I would recommend implementing the equals method in the classes that will be compared, unless you don't have that option (for example, if you don't have the source code for the original class). IDE's like IntelliJ provide support for the "equals" and "hashcode" methods creation (in IntelliJ, you provide the fields that will be compared and which fields can be null or not). For this particular case, I would say go with these tools.
There is one case where I think that an implementation using Reflection would be useful - in a unit test, if you want to throw an assertion error if the equality is no true, you can actually throw an assertion for the exact field that is failing, and not just a generic "object is not the same" assertion error - even in this case, I would perform an equals after my original validation just to be sure that the objects are the same, or at least that the equals method is implemented and working properly.
PS: If you want to get rid of all this coding check the Beans Common library;
PS 2: Reflection is not bad, and it is used everywhere where you don't have an explicit code call - Spring configuration files, for example. Just don't abuse it.
As you are looking only for "properties" you could use commons beanutils and more precisely this class...
(I guess you cannot implement .equals because your objects don't share the same type...)
I believe you're testing for unnecessary cases in your if statements, and can reduce them to this:
if ( arcMethodValue == null ) {
if ( methodValue != null) {
return false;
}
} else if ( !arcMethodValue.equals( methodValue ) ) {
return false;
}
Also, you're calling method.getName() 4 times, you could create a variable and then use it.
Your return code is unnecessarily complicated. The standard idiom for comparison of reference types is this:
(field1 == null) ? (field2 == null) : field1.equals(field2);
This is much clearer and is pretty standard (Effective Java 2nd Edition, page 43).
Update:
There was a confusion since earlier I had written return [idiom]. Yes, in this case a return would not be what the original poster want. He would want if ![idiom] return false; instead. My point is that the [idiom] works, and it's much better.