Why isn't there an Optional.or(Optional default) method? - java

Is there a way to make the following code sample more concise?
final FluentIterable<AuthContext> withEmails = // ...
final Optional<AuthContext> verified = withEmails.firstMatch(VERIFIED_EMAIL);
if (verified.isPresent()) {
return verified.get();
}
return withEmails.first().orNull();
I was trying to do something like return verified.or(withEmails.first()) but there is no appropriate method in Optional.
Alternatively return verified.or(withEmails.first().orNull()) will fail when the orNull() method returns null.

Just do verified.or(withEmails.first()).orNull();.
Depending on the return type of your method and your IDE of choice, the type inference may not suggest this as it returns another Optional of type T rather an a T itself.
c.f. Optional#or(Optional)

Related

How to interpret and use Java 1.8 Optional Class

This is a code segment from another StackOverflow question:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return ofNullable(entityValue).map(entityUuid -> entityUuid.toString()).orElse(null);
}
I am really struggling to understand the use of the Optional class. Is the return code saying "return the value of the map (a String) or NULL if that fails?
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
This is a really bad use of Optional. In fact the java developers themself say that optional should not be used in such cases, but only as a return argument from a method. More can be read in this great answer: Is it good practice to use optional as an attribute in a class
The code can be rewritten to this:
#Override
public String convertToDatabaseColumn(final UUID entityValue) {
return entityValue == null ? null : entityValue.toString();
}
Is the return code saying "return the value of the map (a String) or NULL if that fails?
Yes. You can check the documentation of Optional here. It tells you exactly what map and orElse do.
How can return be acting on a method rather than a Class - that is Optional.ofNullable()?
You are not returning the method. You are returning the return value of a method. Look at this simple example:
int myMethod() {
return foo();
}
int foo() { return 10; }
See? I am not returning foo the method, I am returning 10, the return value of foo.
Note that it is possible to return methods, with functional interfaces.
In this case, you are returning the return value of the last method in the method chain, orElse. ofNullable creates an Optional<T>, then map is called on this object and returns a new Optional<T>, then orElse is called and its return value is returned.
Lets go step by step:
ofNullable(entityValue)
creates an Optional of the incoming parameter (which is allowed to be null, using of() a NPE gets thrown for null input)
.map(entityUuid -> entityUuid.toString())
Then you pick the actual value, and invoke toString() on that value ... which only happens if entityValue isn't null. If it is null, the result comes from orElse(null).
In the end, the result of that operation on the Optional is returned as result of the method.
The above code is nothing but a glorified version of
if (entityValue == null) return null;
return entityValue.toString();
Optionals have their place in Java, but your example isn't a good one.
It doesn't help readability a bit, and you are not alone with wondering "what is going on here".
The code can be turn like this :
public String convertToDatabaseColumn(final UUID entityValue) {
if(entityValue==null){
return null;
}else{
return entityValue.toString();
}
}
Your initial code have two statements:
Optional.ofNullable(entityValue): create an Optional Object to say the value can be present or not.
.map(entityUuid -> entityUuid.toString()).orElse(null); you apply some operation to your Optional object, return a string of it or null.
This will avoid a null pointer exception in a more elegant way.
Optional.ofNullable(T value):
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
Optional.orElse(null)
Return the value if present, otherwise return null.
Follow this link

What to return when generic methods returns 'nothing' but null can't be returned?

Suppose I have a library method like this (very abbreviated):
public static <V> Optional<V> doSomethingWith(Callable<V> callable) {
try {
return Optional.of(callable.call());
} catch (Exception ex) {
// Do something with ex
return Optional.empty();
}
}
And I want to something that doesn't return a value, like:
Library.</*What1*/>doSomethingWith(() -> {
foo();
return /*what2*/;
});
My first instinct for a generic method that doesn't return a value is making the type Void and returning null, however because the result gets wrapped in an Optional this would throw an exception.
What are reasonable placeholders for /*What1*/ and /*what2*/ that don't look totally random like Integer and 0?
[edit]
I'm trying to avoid Optional.ofNullable because empty is used here to indicate that callable.call() did not complete normally.
If you need a type hint for a generic parameter that will never be used you can use Void, the JDK does this too in some cases, e.g. when converting Runnable into CompletableFuture<T> it uses Void for T.
If you use Optional.ofNullable then you can just return null for what2, which is the only valid value for Void.
[edit] I'm trying to avoid Optional.ofNullable because empty is used here to indicate that callable.call() did not complete normally.
Then you're using the wrong tool for the job. CompletionStage or CompletableFuture has the right semantics.
I usually use Boolean.TRUE to mark success, but you could return Void.class as well. Both are cheap in the sense that not every return creates a new object to be discarded. Though Class<Void> is not just Void it may serve the purpose of labelling something as void just as well.
As already mentioned you could also create your own Result-class/-enum.
Or you could of course return Optional.<Void>nothing(), too. This would result in some Optional<Optional<Void>>, but also do the trick.
If you think all of the above is ugly, I fear that the API probably isn't to well tailored to your needs. Raise an issue/pull request or look for something else.
You could also create your own type similar to Void
public class Result {
public static final Result OK = new Result();
private Result(){}
}
and then return Result.OK.
You can also enhance this type to represent also errors, if you need.
But maybe using java Void is preferable if you don't need anything special.
Use Void for the return type, which is the logical choice for "nothing", but actually return an instance of Void.
Although the javadoc for Void says it's:
...an uninstantiable placeholder class...
You can nevertheless instantiate it:
try {
Constructor<Void> c = Void.class.getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
} catch (Exception perfunctory) {
return null; // won't happen
}

Java Void type - possible/allowed values?

1) In Java, I can do this:
Void z = null;
Is there any other value except null I can assign to z?
2) Consider the following code snipped:
Callable<Void> v = () -> {
System.out.println("zzz");
Thread.sleep(1000);
return null;
};
This compiles OK, but if I remove the last statement return null; it doesn't. Why? After all, Void is supposed to mean no return value.
From the docs:
The Void class is an uninstantiable placeholder class to hold a reference to the Class object representing the Java keyword void.
So, no.
Void is used by methods having to return an object, but really returning nothing.
A decent example can be observed with some usage of the AsyncTask in Android, in cases where you don't need to return any object after the task is complete.
You would then extend AsyncTask<[your params type], [your progress type], Void>, and return null in your onPostExecute override.
You wouldn't need it in most cases though (for instance, Runnable is typically more suitable than Callable<Void>).
Ansering your question more specifically:
But if I remove the return null it does not compile?! Why?
... because a Void is still an object. However, it can only have value null.
If your method declares it returns Void, you need to (explicitly) return null.
If you check the sources:
package java.lang;
public final class Void {
public static final Class<Void> TYPE = Class.getPrimitiveClass("void");
private Void() {
}
}
Void is:
final class;
has private constructor.
Without using Reflection it's not possible to assign anything but null to a reference of Void type.
In Java, I can do this Void z = null; Is there any other value (but null) which I can assign to z ?
You can if you create you own Void instances. You can use Reflection or Unsafe to create these, not that it's a good idea.
But if I remove the return null it does not compile?! Why? After all, Void is supposed to mean just that - no return type.
Java is case sensitive, this means that Boolean and boolean are NOT the same type nor is Void and void. Void is a notional wrapper for void but otherwise is just a class you shouldn't create any instance of.
Maybe what you are asking for is Runnable or Consumer - some interface that doesn't have a return value. Void only serves to show that you cannot expect anything else than null. It is still just a class, not a keyword or anything special. A class that cannot be instantiated, so you have to return null.
A lot of efforts were spent in designing lambda expression to treat int/Integer etc indistinguishably, so that int->Long will be compatible with Integer->long, etc.
It is possible (and desirable) to treat void/Void in a similar way, see comments from Goetz and Forax.
However, they didn't have the time to implement the idea for java8 :(
You can introduce an adapter type that is both ()->void and ()->Void; it can simplify your use case a little bit, see http://bayou.io/release/0.9/javadoc/bayou/util/function/Callable_Void.html
If you have a method that accepts ()->Void, it is not going to work well with ()->void lambdas. One workaround is to overload the method to accept ()->void. For example, ExecutorService
submit(Callable<T> task)
submit(Runnable task)
...
submit( System::gc ); // ()->void
However, overloading with functional parameter types is tricky... The example above works because both accept a zero-arg function. If the function has non-zero args
foo( Function<String,Void> f ) // String->Void
foo( Consumer<String> f ) // String->void
it's confusing to the compiler (and the programmer)
foo( str->System.out.println(str) ); // which foo?
foo( System.out::println ); // which foo?
Given an implicit lambda str->expr, the compiler needs a target type to make sense of it. The target type here is given by the method parameter type. If the method is overloaded, we need to resolve method overloading first... which typically depends on the type of the argument (the lambda)... So you can see why it is complicated.
(A zero-arg lambda is never implicit. All argument types are known, since there's no argument.)
The lambda spec does have provisions to resolve the following cases
foo( str->{ System.out.println(str); } );
foo( str->{ System.out.println(str); return null; } );
You may argue that in the previous example,
foo( str->System.out.println(str) );
since println(str) returns void, the Void version obviously does not fit, therefore the compiler should be able to resolve it. However, remember that, to know the meaning of println(str), first, the type of str must be resolved, i.e. method overloading of foo must be resolved first...
Although in this case, str is unambiguously String. Unfortunately, the lambda designer decided against to be able to resolve that, arguing it is too complicated. This is a serious flaw, and it is why we cannot overload methods like in Comparator
comparing( T->U )
//comparing( T->int ) // overloading won't work well
comparingInt ( T->int ) // use a diff method name instead

How I return array of my class type object?

Reedited...
public EventData getEventDetails(String evtId, String Status) {
//do some data selection here.
return evData1;
}
public EventData[] getAdminAuthEvtDetails(String evtId, String Status) {
String eId=evtId;
String status=Status;
EventData[] evData=new EventData[2];
EventData[0] evData=getEventDetails(eId,"V");
EventData[1] evData=getEventDetails(eId,"M");
return evData;
}
EventData is my java data class. In there I set getters and setters. I want to call getEventDetails method two time one status as verified and other as modified for requested ID and set both evData into one array. In here there give a error couldn't get data into EventData[0] and EventData[1].Is there any error of calling my getEventDetails method?
Finally I got correct code.
EventData[] evData=new EventData[2];
evData[0]=getEventDetails(eId,"V");
evData[1]=getEventDetails(eId,"M");
return evData;
in both methods you must return an object rather than Type
in 1st method:
public EventData getEventDetails(String evtId, String Status) {
return new EventData(evtId, status);//don't know how is you constructor of EventData, but its just a smart guess. the idea is to create an object
}
and in 2nd method return eData;
I believe you need to update your getEventDetails method as well. EventData is a class however you need to return an instance of the class generally created by calling the constructor new EventData().
Otherwise, ay89 is correct that getAdmin... should return eData.
Conceptually, it's correct. You just have some syntax issues that others have mentioned (like returning a variable instead of a class).
Otherwise, some other things to note:
You'll want to probably use a lowercase "s" for "Status" since conventionally, variables shouldn't start with upper cases.
You probably dont need to redeclare the evtId to eid. You can just use the evtId (and the incorrectly cased Status) variable directly.
Personally, I like to perhaps call the getEventDetails(...) method something more like createEventDetails(...) since it's more indicative of the function of that method. "Get" always implies fetching instead of creating to me.
Just my 2c

java reflection issue

I have this code:
public static final <TypeVO extends BaseVo> List<SelectItem> populateSelectBoxForType(
final Class<TypeVO> voClass, final String fieldName) {
List<SelectItem> listSelectBox = null;
final List<TypeVO> vosList = GenericEjbProxyFactory
.getGenericTopValueObjectProxy(voClass)
.getAllValueObjects(null);
System.out.println("loaded vosList!!!!");
if (vosList != null) {
listSelectBox = new ArrayList<SelectItem>();
for (final TypeVO currVo : vosList) {
listSelectBox.add(new SelectItem(currVo.getInternalId(), currVo.getName()));
}
}
return listSelectBox;
}
As you see here, I'm using currVo.getName because always, currVo has a name property.
I want to be able to use also other fields from this currVo which has type as voClass, but not all currVo classes will contain this field so I have to use reflection to identify these getField method, something like:
for (final TypeVO currVo : vosList) {
for (final Method m : voClass.getMethods()) {
if (m.getName().contains(fieldName)) {
listSelectBox.add(new SelectItem(
currVo.getInternalId(), currVo.m));
}
}
}
What I do not know is HOW I can use that specific method's value when I find it, exactly like currVo.getName (because, of course, currVo.m is wrong)?
Eg: If fieldName is "Age" I want to put in the list: currVo.getAge()... I am simply blocked here...
m.invoke(currVo);
See also:
Method javadoc
Also note the correct way to look for a method as suggested by Nik and Bohemian.
Do I understand it correctly that you want to invoke the method m on your object currVo? Then it's simply
m.invoke(currVo);
Use reflection to get the getFieldName method and invoke it, as follows:
Method method = voClass.getMethod("get" + fieldName); // the getter with no params in the signature
Object value = method.invoke(currVo}); // invoke with no params
listSelectBox.add(new SelectItem(currVo.getInternalId(), value));
Note: This assumes that fieldName is leading uppercase, eg "Value", not "value", so prepending it with "get" gives the exact method name, eg "getValue"
You should use the invoke method from the Method class.
m.invoke(currVo, (Object[]) null);
(Assuming the method takes no parameter.)
This will work for JDK versions 1.4 and later, since they state:
If the number of formal parameters required by the underlying method is 0, the supplied args array may be of length 0 or null
The one-parameter version of that call will not work on older JVMs.
I am not sure if i got ur question right, but what i feel u are asking wud be answered by following code:
// Class is whatever is the type u r using
Method mthd = Class.getMethod("get" + fieldName); //in case method don't have any parameters.
listSelectBox.add(mthd.invoke(currVo));
otherwise ignore.

Categories