Optionally getting field - java

I have a class structure like this:
public class Foo {
private FooB foob;
public Optional<FooB> getFoob() {
return Optional.ofNullable(foob);
}
}
public class FooB {
private int valA;
public int getValA() {
return valA;
}
}
My objective is to call the get method for fooB and then check to see if it's present. If it is present then return the valA property, if it doesn't then just return null. So something like this:
Integer valA = foo.getFoob().ifPresent(getValA()).orElse(null);
Of course this isn't proper Java 8 optional syntax but that's my "psuedo code". Is there any way to achieve this in Java 8 with 1 line?

What you are describing is the method Optional.map:
Integer valA = foo.getFoob().map(foo -> foo.getValA()).orElse(null);
map lets you transform the value inside an Optional with a function if the value is present, and returns an empty the optional if the value in not present.
Note also that you can return null from the mapping function, in which case the result will be Optional.empty().

Why you dont add a getValue methode to the class Foo? This would be a kind of delegation.
public class Foo {
...
public Integer getValue() {
if (foob == null) {
return null;
}
return foob.getValA();
}
}

Related

check each object, return true when the first condition is met, else return false

I have a method that works fine. This is how it looks.
private ArrayList<Car> carsInStore ; //in car class have setter/getter/quals/Constructor.
public boolean checkIfcarInStore(Car c) {
for (Car car : carsInStore) {
if(car.equals(c)){
return true;
}
}
}
I want to switch this to Lambda.
But I am not sure how fill in the if (condition) return true or return false outside.
And I know I can do it in stream too. Can anyone give an example?
If you really want to use lambda, this should work else you have your answer within your comment.
private ArrayList<Car> carsInStore ;
public boolean checkIfcarInStore(Car c) {
return carsInStore.stream().anyMatch(c::equals);
}
}
You can substitute the method checkIfcarInStore() with a Predicate, which is a functional interface representing a boolean condition, that can be implemented as a lambda expression:
Predicate<Car> isInStore = car -> carsInStore.contains(car);
or as a method reference:
Predicate<Car> isInStore = carsInStore::contains;
If according to the instructions of your assignment you need to have a method checkIfcarInStore(), the predicate can be declared as a field and used internally inside the method:
private ArrayList<Car> carsInStore ;
private Predicate<Car> isInStore = car -> carsInStore.contains(car);
public boolean checkIfCarInStore(Car car) {
return isInStore.test(car);
}

Graceful alternative to nested Optional.map?

I have multiple Optionals that must be mapped to a POJO. Is there a better alternative than the following?
class SimplePojo {
private String stringField;
private Integer integerField;
// All args. constructor, getter, setter
}
Optional<String> stringOptional = ...
Optional<Integer> integerOptional = ...
Optional<SimplePojo> simplePojoOptional = stringOptional.flatMap(
string -> integerOptional.map(integer -> new SimplePojo(string, integer)))
I have reduced the problem to 2 Optionals in the above example to keep it short. But I actually have 3 Optionals with more on the way. I am afraid the last line can easily become unwieldy soon.
Please note: Use of functional frameworks like Vavr or Functional Java is not an option for me.
How about using a Builder ?
class SimplePojo {
public static class Builder {
private String stringField;
public Builder withStringField(String str) {
this.stringField = str;
return this;
}
// and other "with" methods...
public Optional<SimplePojo> build() {
if (stringField == null || anotherField == null /* and so forth */) {
return Optional.empty();
} else {
return Optional.of(new SimplePojo(this));
}
}
}
private final String stringField;
/* private constructor, so client code has to go through the Builder */
private SimplePojo(Builder builder) {
this.stringField = builder.stringField;
// etc.
}
}
Then you could use it as follows:
SimplePojo.Builder builder = new SimplePojo.builder();
optionalStringField.ifPresent(builder::withStringField);
// etc.
return builder.build();
I do not see any advantage from pursuing the functional style this way here. see three options:
ONE: If you can alter the SimplePojo class and if this scenario is a common one, you might consider to add a factory method to the SimplePojo:
class SimplePojo {
public static Optional<SimplePojo> of(final Optional<String> stringField, final Optional<Integer> integerField) {
if (stringField.isPresent() && integerField.isPresent()) {
return new SimplePojo(stringField.get(), integerField.get());
else
return Optional.empty();
}
}
TWO: If you cannot alter the SimplePojo, you might want to create this as a utility method somewhere else. If you need this pattern only in one class, make the method private in this class!
THREE: If you need to do this only once or twice, I would prefer the if...then construction from the first option over the functional notation you used for the sake of readability:
final Optional<SimplePojo> simplePojoOptional;
if (stringField.isPresent() && integerField.isPresent()) {
simplePojoOptional = new SimplePojo(stringField.get(), integerField.get());
else
simplePojoOptional = Optional.empty();

creating a custom argument matcher confusing implementation

I have seen someone creating a custom argument matcher like the following. However, I am having difficulty understanding how it works.
What I can understand its a method that takes a parameter and returns a ArgumentMatcher which is an interface that has a type of List<Person>. And the overriden method is the matcher that uses a lambda. I think the body part is the most confusing, if anyone can explain that.
private ArgumentMatcher<List<Person> personListSize(final int size) {
return argument -> argument.personList().size() == size;
}
This is the way I would normally do something like this, which to me is easier to understand, just wondering how can I get the following to look like the above?
public class CustomArgumentMatcher implements ArgumentMatcher<List<Person>> {
#Override
public boolean matches(List<Person> argument) {
return argument.size() == size;
}
}
Just starting to understand, this works:
private ArgumentMatcher<String> stringMatcher = new ArgumentMatcher<String>() {
#Override
public boolean matches(String argument) {
return argument.contains("");
}
};
However, If I add a parameter to pass in like this:
private ArgumentMatcher<String> stringMatcherArgs(final String name) = new ArgumentMatcher<String>() {
}
I get a error message saying unexpected token just wondering to pass in a parameter in the above?
You should read this document about Lambda Expressions
Here are your examples:
private ArgumentMatcher<List<Person>> customArgumentMatcher(final int size) {
return argument -> argument.size() == size;
}
private ArgumentMatcher<List<Person>> stringMatcherArgs(final String name) {
return argument -> argument.contains(name);
}
You got it all correct just connect the dots...
private ArgumentMatcher<List<Person> personListSize(final int size) {
return new ArgumentMatcher<List<Person>>() {
#Override
public boolean matches(List<Person> argument) {
return argument.size() == size;
}
};
}
and use it with argThat
Mockito.verify(mockClass).foo(argThat(personListSize(5));
If your still looking for the kotlin equivalent of Gustavo`s answer
(note that you should have created another question instead),
try the following:
fun customArgumentMatcher(size : Int) : ArgumentMatcher<List<Person>> {
return object : ArgumentMatcher<List<Person>> {
override fun matches(argument : List<Person>) = argument.size == size;
}
}
See also:
Setting anonymous interface in Kotlin

checking whether an object is present in a List of Objects on the basis of some member variable

suppose I have defined a List as
private BlockingQueue<MyDelayed> DelayedIds = new DelayQueue<>();
class MyDelayed is like:
private class MyDelayed implements Delayed {
private String myId;
private Long creationTime;
MyDelayed (String myId) {
this.myId= myId;
this.creationTime = System.currentTimeMillis();
}
String getMyId() {
return this.myId;
}
#Override
public long getDelay(TimeUnit unit) {
//TODO
}
#Override
public int compareTo(Delayed o) {
//TODO
}
}
Now suppose that I want to add an Object of class MyDelayed in DelayedIds list.
I can do it by using add function.
But If I want to add obbject in list only if list does not contain an object of class MyDelayed which has the same myId attribute which I am trying to insert.
Obviously DelayedIds .contains(new MyDelayed(myId)) will not work.
Is there any easy way to check this thing ?
Am I missing something ?
You could write something like this and compare every element in the list to see if it contains your id. If at any point you find a matching one you return true, if the loop finished having found none it returns false.
public boolean contains(String id){
for (MyDelayed md : DelayedIds){
if(md.getMyId().equals(id)){
return true;
}
}
return false;
}
Now to check before adding you would do something like:
if(!contains(myNewObject.getMyId())){
DelayedIds.add(myNewObject)
}
Also, I'd suggest that you rename DelayedIds to delayedIds in order to follow coding standards (see Variables).

A suitable pattern instead of returning nulls

What would be a good pattern to use here?
I donĀ“t want to return nulls, that just does not feel right.
Another thing is, what if I want to return the reason that causes it to null? If caller knows why it is null, it can do some extra things so I want caller knows it and acts that way
Public CustomerDetails getCustomerDetails(){
if(noCustomer){
..log..etc..
return null;
}
if(some other bad weird condition){
..log..etc..
return null;
}
CustomerDetails details= getCustomerDetailsFromSomewhere();
if (details!=null){
return details;
}
else {
..log..etc..
return null;
}
}
I think you have 3 main options:
If null is a valid state I see no problem in returning null
If null is an invalid state you should throw an exception
Or make use of the Null object pattern
If you are using googles Guava libraries you can also use the Optional class.
The more natural way in Java is to throw an exception on an error condition.
public CustomerDetails getCustomerDetails(){
if(noCustomer){
..log..etc..
throw new NoSuchCustomer(customerName);
}
if(some other bad weird condition){
..log..etc..
throw new IllegalStateException("some other bad weird condition occurred");
}
CustomerDetails details= getCustomerDetailsFromSomewhere();
if (details==null)
throw new IllegalStateException("Failed to get customer details for "+ customerName);
return details;
}
The method getCustomerDetailsFromSomewhere() could throw an exception instead of returning null.
If you mean that the null does not explain its state, you can wrapper CustomerDetails with another class that can give more details. For example:
class Feedback()
{
private CustomerDetails result;
private int status;
public static final int STATUS_OK = 0;
public static final int STATUS_NULL = 1;
public static final int STATUS_NO_CUSTOMER = 2;
public static final int STATUS_BAD_CONDITION = 3;
public Feedback(CustomerDetails result, int status)
{
this.result = result;
this.status= status;
}
public CustomerDetails getResult(){return result;}
public int getStatus(){return status;}
}
and change your method with:
Public Feedback getCustomerDetails()
{
if(noCustomer)
{
..log..etc..
return new Feedback(null, Feeback.STATUS_NO_CUSTOMER);
}
if(some other bad weird condition)
{
..log..etc..
return new Feedback(null, Feeback.STATUS_BAD_CONDITION);
}
CustomerDetails details = getCustomerDetailsFromSomewhere();
if(details != null)
{
return new Feedback(details, Feeback.STATUS_OK);
}
else
{
..log..etc..
return new Feedback(null, Feeback.STATUS_NULL);
}
}
Then you can get the status by feedback.getStatus().
Try Guava's Optional. See this article on avoiding null: http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained
Use Google Guava Optional.
This will help.
Many of the cases where programmers use null is to indicate some sort
of absence: perhaps where there might have been a value, there is
none, or one could not be found. For example, Map.get returns null
when no value is found for a key.
Optional is a way of replacing a nullable T reference with a
non-null value. An Optional may either contain a non-null T reference
(in which case we say the reference is "present"), or it may contain
nothing (in which case we say the reference is "absent"). It is never
said to "contain null."
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
You could try;
CustomerDetails details = setDetailsToEmpty();
or some equivalent.
You still have to check, either for null or empty customer details.
If you really don't want null create a special CustomerDetails object
...
public static final CustomerDetails EMPTY_CUSTOMER_DETAILS = new CustomerDetails();
...
public CustomerDetails getCustomerDetails(){
...
if (details!=null){
return details;
}
...
return EMPTY_CUSTOMER_DETAILS;

Categories

Resources