I have a validate() method that checks the arguments passed in a rest url.
The arguments are linked to a model class like the following
class SearchCriteria {
String regno;
String hostid;
String domid;
String location;
String provider;
/*Getters and Setters*/
}
I have a utility class that checks if the arguments are set or not.
public class SearchCriteriaUtil {
public static boolean isRegnoSet(SearchCriteria criteria) {
return null != criteria.getRegno();
}
public static boolean isHostIdSet(SearchCriteria criteria) {
return null != criteria.getHostId();
}
/* Similarly for domid, location, provider */
}
I have a predicate that tests based on the conditions provided in the util and generates a Truth Value String
public class ParameterPredicate<T> implements Predicate<T>{
final Predicate<T> predicate;
final String sequence;
public ParameterPredicate(Predicate<T> predicate, String sequence) {
this.predicate = predicate;
this.sequence = sequence;
}
#Override
public String toString() {
return sequence;
}
#Override
public boolean test(T t) {
return predicate.test(t);
}
}
Now, based on the arguments set/notset,
regno -set, hostid -set, domid - notset, location - notset, provider - set
My Predicate should evaluate based on the conditions in SearchCriteriaUtil and set the sequence to the appropriate Truth Values...in this case "T T F F T"
In my validate method,
public void validateCriteria(SearchCriteria criteria) {
List<Predicate<SearchCriteria>> SearchCriteriaPredicate = Arrays.asList(SearchCriteriaUtil::isRegnoSet, SearchCriteriaUtil::isHostIdSet,
SearchCriteriaUtil::isDomidSet,
SearchCriteriaUtil::isLocationSet,
SearchCriteriaUtil::isProviderSet,
Collection<String> desired = Arrays.asList("T F F F F", "T F T T F", "T F T T F", "T F F F T", "T F F F T", "F T F F F");
I am not able to proceed beyond this point, I have to set the sequence and check if it exists in the desired list of truth values.
I was refering to a previous post : Filtering with truth tables
As I am new to java 8, any help is appreciated.
Instead of using a util class and dealing with Strings in order to check if a combination of criteria is valid, why not just add something like the following inside your SearchCriteria class:
public boolean hasDesiredCombination() {
return Criterion.DESIRED_COMBINATONS.contains(
Arrays.stream(Criterion.values())
.filter(s -> s.predicate.test(this))
.collect(Collectors.toCollection(
() -> EnumSet.noneOf(Criterion.class)))
);
}
private static enum Criterion {
REGNO(s -> s.regno != null),
HOSTID(s -> s.hostid != null),
DOMID(s -> s.domid != null),
LOCATION(s -> s.location != null),
PROVIDER(s -> s.provider != null);
private static Set<Set<Criterion>> DESIRED_COMBINATONS =
new HashSet<>(Arrays.asList(
EnumSet.of(REGNO),
EnumSet.of(REGNO, DOMID, LOCATION),
EnumSet.of(REGNO, PROVIDER),
EnumSet.of(HOSTID)
));
private Predicate<SearchCriteria> predicate;
private Criterion(Predicate<SearchCriteria> predicate) {
this.predicate = predicate;
}
}
Advantages:
You don't necessarily have to expose getters and setters
It's immediately clear from the source code which combinations are desired
The logic is where it belongs: (indirectly) inside the SearchCriteria class
I'm not sure what the purpose of ParameterPredicate is, but if I've understood correctly, you want check whether a combination of validations (SearchCriteriaPredicate) matches one of a predefined set (desired). If so, this should do it:
String sequence = SearchCriteriaPredicate.stream()
.map(p -> p.test(criteria) ? "T" : "F")
.collect(Collectors.joining(" "));
return desired.contains(sequence);
Related
I'd like to use something like this to check some conditions, but the problem is that I need to know which condition failed and log the exception, this way does achieve it but relies on knowing the position at which it was checked inside the code which isn't ideal, is there any other nicer way of doing this? (without making calling the function much longer)
matchOrThrow(
() -> 1 == 2,
() -> 1 == 1,
() -> a > b,
() -> c == null
);
public static void matchOrThrow(BooleanSupplier... conditions) {
int i = 1;
for (BooleanSupplier condition : conditions) {
if (Boolean.FALSE.equals(condition.getAsBoolean())) {
throw new CustomException("Condition check n_" + i + " failed");
}
i++;
}
}
You might be interested at looking at the Decorator design patter.
Namely, you can create a decorating implementation of the Functional interface of your choice. It seems like you Predicate is more suitable for than a BooleanSupplier, therefore the example below illustrates a throwing Predicate, which expects a predicate, producer of the target exception, message and logger as arguments and its implementation of test() delegates to the wrapped predicate to evaluate the condition.
The instances of the trowing Predicate can be used anywhere, where Predicate is expected.
public class ThrowingLoggPredicate<T> implements Predicate<T> {
private Predicate<T> predicate;
private Function<String, RuntimeException> exceptionFactory;
private String messageShort;
private String format;
private Logger logger;
public ThrowingLoggPredicate(Predicate<T> predicate,
Function<String, RuntimeException> exceptionFactory,
String messageShort, String format,
Logger logger) {
this.predicate = predicate;
this.exceptionFactory = exceptionFactory;
this.messageShort = messageShort;
this.format = format;
this.logger = logger;
}
public boolean test(T t) {
if (!predicate.test(t)) {
RuntimeException e = exceptionFactory.apply(messageShort);
String messageVerbose = String.format(format, t);
logger.log(Level.ERROR, messageVerbose, e);
throw e;
}
return true;
}
public static <T> boolean allMatch(Collection<Predicate<T>> predicates, T t) {
return predicates.stream().allMatch(p -> p.test(t));
}
}
I want to dynamic search with Criteria API in Java.
In the code I wrote, we need to write each entity in the url bar in JSON. I don't want to write "plaka".
The URL : <localhost:8080/api/city/query?city=Ankara&plaka=> I want to only "city" or "plaka"
Here we need to write each entity, even if we are going to search with only 1 entity. Type Entity and it should be empty.
My code is as below. Suppose there is more than one entity, what I want to do is to search using a single entity it wants to search. As you can see in the photo, I don't want to write an entity that I don't need. can you help me what should I do?
My code in Repository
public interface CityRepository extends JpaRepository<City, Integer> , JpaSpecificationExecutor<City> {
}
My code in Service
#Service
public class CityServiceImp implements CityService{
private static final String CITY = "city";
private static final String PLAKA = "plaka";
#Override
public List<City> findCityByNameAndPlaka(String cityName, int plaka) {
GenericSpecification genericSpecification = new GenericSpecification<City>();
if (!cityName.equals("_"))
genericSpecification.add(new SearchCriteria(CITY,cityName, SearchOperation.EQUAL));
if (plaka != -1)
genericSpecification.add(new SearchCriteria(PLAKA,plaka, SearchOperation.EQUAL));
return cityDao.findAll(genericSpecification);
}
#Autowired
CityRepository cityDao;
My code in Controller
#RestController
#RequestMapping("api/city")
public class CityController {
#Autowired
private final CityService cityService;
public CityController(CityService cityService) {
this.cityService = cityService;
#GetMapping("/query")
public List<City> query(#RequestParam String city, #RequestParam String plaka){
String c = city;
int p;
if (city.length() == 0)
c = "_";
if (plaka.length() == 0) {
p = -1;
}
else
p = Integer.parseInt(plaka);
return cityService.findCityByNameAndPlaka(c,p);
}
My code in SearchCriteria
public class SearchCriteria {
private String key;
private Object value;
private SearchOperation operation;
public SearchCriteria(String key, Object value, SearchOperation operation) {
this.key = key;
this.value = value;
this.operation = operation;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
public SearchOperation getOperation() {
return operation;
}
My code in GenericSpecification
public class GenericSpecification<T> implements Specification<T> {
private List<SearchCriteria> list;
public GenericSpecification() {
this.list = new ArrayList<>();
}
public void add(SearchCriteria criteria){
list.add(criteria);
}
#Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<>();
for (SearchCriteria criteria : list) {
if (criteria.getOperation().equals(SearchOperation.GREATER_THAN)) {
predicates.add(builder.greaterThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN)) {
predicates.add(builder.lessThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.GREATER_THAN_EQUAL)) {
predicates.add(builder.greaterThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN_EQUAL)) {
predicates.add(builder.lessThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.NOT_EQUAL)) {
predicates.add(builder.notEqual(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.EQUAL)) {
predicates.add(builder.equal(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.MATCH)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
"%" + criteria.getValue().toString().toLowerCase() + "%"));
} else if (criteria.getOperation().equals(SearchOperation.MATCH_END)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
criteria.getValue().toString().toLowerCase() + "%"));
}
}
return builder.and(predicates.toArray(new Predicate[0]));
}
My code in SearchOperation
public enum SearchOperation {
GREATER_THAN,
LESS_THAN,
GREATER_THAN_EQUAL,
LESS_THAN_EQUAL,
NOT_EQUAL,
EQUAL,
MATCH,
MATCH_END,
}
The good thing about the Criteria API is that you can use the CriteriaBuilder to build complex SQL statements based on the fields that you have. You can combine multiple criteria fields using and and or statements with ease.
How I approached something similar int he past is using a GenericDao class that takes a Filter that has builders for the most common operations (equals, qualsIgnoreCase, lessThan, greaterThan and so on). I actually have something similar in an open-source project I started: https://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/dao/GenericDao.java
https://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/filter/JPAFilter.java
Next, the implicit DAO class extends this GenericDao and when I want to do an operation (ex: find a user with the provided username) and there I create a Filter.
Now, the magic is in the filter. This is the one that creates the Predicate.
In your request, you will receive something like this: field1=something&field2=somethingElse and so on. The value can be preceded by the '<' or '>' if you want smaller or greater and you initialize your filter with the values. If you can retrieve the parameters as a Map<String, String>, even better.
Now, for each field in the request, you create a predicate using the helper methods from the JPAFilter class and return he resulted Predicate. In the example below I assume that you don't have it as a Map, but as individual fields (it is easy to adapt the code for a Map):
public class SearchFilter extends JPAFilter {
private Optional<String> field1 = Optional.empty();
private Optional<String> field2 = Optional.empty();
#Override
public Predicate getPredicate(CriteriaBuilder criteriaBuilder, Root root) {
Predicate predicateField1 = field1.map(f -> equals(criteriaBuilder, root, "field1", f)).orElse(null);
Predicate predicateField2 = field2.map(f -> equals(criteriaBuilder, root, "field2", f)).orElse(null);
return andPredicateBuilder(criteriaBuilder, predicateField1, predicateField2);
}
}
Now, I have the fields as Optional since in this case I assumed that you have them as Optional in your request mapping (Spring has this) and I know it is a bit controversial to have Optional as input params, but in this case I think it is acceptable (more on this here: https://petrepopescu.tech/2021/10/an-argument-for-using-optional-as-input-parameters/)
The way the andPredicateBuilder() is made is that it works properly even if one of the supplied predicates is null. Also, I made s simple mapping function, adjust to include for < and >.
Now, in your DAO class, just supply the appropriate filter:
public class SearchDao extends GenericDAO {
public List<MyEntity> search(Filter filter) {
return get(filter);
}
}
Some adjustments need to be made (this is just starter code), like an easier way to initialize the filter (and doing this inside the DAO) and making sure that that the filter can only by applied for the specified entity (probably using generics, JPAFIlter<T> and having SearchFilter extends JPAFilter<MyEntity>). Also, some error handling can be added.
One disadvantage is that the fields have to match the variable names in your entity class.
I have the following scenario: two validation Helpers
the StringValidationHelper ...
public class StringValidationHelper {
public static Validation<String> notNull =
SimpleValidation.from(s -> s != null, "must not be null.");
public static Validation<String> moreThan(int size) {
return SimpleValidation.from(
s -> s.length() >= size,
String.format ("must have more than %s chars.", size));
}
... // More methods (lessThan, etc)}
... and NumberValidationHelper.
public class NumberValidationHelper {
public static Validation<Number> notNull =
SimpleValidation.from(n -> n != null, "must not be null");
public static <N extends Number & Comparable<N>> Validation<N> lowerThan(N max){
return SimpleValidation.from(
n -> n.compareTo(max) == -1,
String.format("must be lower than %s.", max));
}
... // More methods like (greaterThan, etc)}
The method from is a static factory method that receives a Predicate and a message to eventual validation fails.
public class SimpleValidation<K> implements Validation<K>{
private Predicate<K> predicate;
private String onErrorMessage;
private SimpleValidation(Predicate<K> predicate, String onErrorMessage) {
this.predicate = predicate;
this.onErrorMessage = onErrorMessage;
}
public static <K> SimpleValidation<K> from(Predicate<K> predicate, String onErrorMessage){
return new SimpleValidation<>(predicate, onErrorMessage);
}
... // Omitted for simplicity
}
Thanks to the Validation interface, you can enjoy a wonderfully smooth interface
#FunctionalInterface
public interface Validation<K> {
... // Omitted for simplicity
default Validation<K> and(Validation<K> other) {
return param -> {
ValidationResult firstResult = this.test (param);
return ! firstResult.isValid()? firstResult: other.test(param);
};
}
... // Omitted for simplicity
}
So I can start, for example, a validation using the closure notNull.
Example: with NumberValidationHelper
public class MyValidate {
void validate(int toValidate) {
notNull.and(lowerThan(100)).test(toValidate).isValid();
}
}
This validation framework I developed based on this article.
Well, notNull enclaves a type-independent behavior, so I'd like to remove the duplication of these two helpers.
I'm not finding an obvious shape without losing the fluid interface.
Because the variable is static, you can not use generics and extend the behavior, for instance.
public abstract class GenericHelper<K> {
public static Validation<K> notNull = SimpleValidation.from(o -> o != null, "must not be null.");
}
Also it does not bother me to type Validation with Object as below:
public abstract class GenericHelper {
public static Validation<Object> notNull = SimpleValidation.from(o -> o != null, "must not be null.");
}
... because in the call chaining, it will give compilation error since the result of notNull will be a Validation< Object > and and will be expecting a Validation< Integer >
notNull.and(lowerThan(100)).test(toValidate).isValid(); //Does not compile
Is there any way to use the Java 8 function features that keep this interface flowing generically, running away from the solutions I've tried above?
thankful
You should relax the generic signature of and, allowing a Validation<T> with a more specific T as parameter, to produce a Validation<T> as result:
default <T extends K> Validation<T> and(Validation<T> other) {
return param -> {
ValidationResult firstResult = this.test(param);
return ! firstResult.isValid()? firstResult: other.test(param);
};
}
Staying with your examples, you still cannot write
void validate(int toValidate) {
notNull.and(moreThan(100)).test(toValidate).isValid();
}
as moreThan returns a Validation<String> which can not test an int, but spotting such errors is what Generics is all about (I suppose, you have another moreThan method in your actual code base which you didn’t include in your question). But the following will now work with your example:
void validate(int toValidate) {
notNull.and(lowerThan(100)).test(toValidate).isValid();
}
Sometimes, you need to test a validation of a more specific type before a more generic validation which still doesn’t work with the method shown above. One solution would be to go the same route as the JDK developers and augment Function.andThen(after) with a Function.compose(before), allowing to swap the roles
default <T extends K> Validation<T> compose(Validation<T> other) {
return param -> {
ValidationResult firstResult = other.test(param);
return ! firstResult.isValid()? firstResult: this.test(param);
};
}
Or you create a static method, which allows both arguments to have a broader type than the resulting Validation:
static <T> Validation<T> and(Validation<? super T> first, Validation<? super T> second) {
return param -> {
ValidationResult firstResult = first.test(param);
return ! firstResult.isValid()? firstResult: second.test(param);
};
}
Note that the static method can be combined with the convenient instance method, so that the caller only needs to resort to the static method when hitting the limitations of the generic signature:
#FunctionalInterface
public interface Validation<K> {
ValidationResult test(K item);
default <T extends K> Validation<T> and(Validation<T> other) {
return and(this, other);
}
static <T> Validation<T> and(Validation<? super T> first,Validation<? super T> second){
return param -> {
ValidationResult firstResult = first.test(param);
return ! firstResult.isValid()? firstResult: second.test(param);
};
}
}
So you can still write
notNull.and(lowerThan(100)).test(toValidate).isValid();
but when hitting the limitation, e.g.
Validation<Object> anotherCriteria;
…
lowerThan(100).and(anotherCriteria).test(toValidate).isValid();
does not work, you can resort to
Validation.and(lowerThan(100), anotherCriteria).test(toValidate).isValid();
I was reading an article linked from a slashdot story, and came across this little tidbit:
Take the latest version of Java, which
tries to make null-pointer checking
easier by offering shorthand syntax
for the endless pointer testing. Just
adding a question mark to each method
invocation automatically includes a
test for null pointers, replacing a
rat's nest of if-then statements, such
as:
public String getPostcode(Person person) {
String ans= null;
if (person != null) {
Name nm= person.getName();
if (nm!= null) {
ans= nm.getPostcode();
}
}
return ans
}
With this:
public String getFirstName(Person person) {
return person?.getName()?.getGivenName();
}
I've scoured the internet (okay, I spent at least 15 minutes googling variations on "java question mark") and got nothing. So, my question: is there any official documentation on this? I found that C# has a similar operator (the "??" operator), but I'd like to get the documentation for the language I'm working in. Or, is this just a use of the ternary operator that I've never seen before.
Thanks!
EDIT: Link to the article: http://infoworld.com/d/developer-world/12-programming-mistakes-avoid-292
The original idea comes from groovy. It was proposed for Java 7 as part of Project Coin: https://wiki.openjdk.java.net/display/Coin/2009+Proposals+TOC (Elvis and Other Null-Safe Operators), but hasn't been accepted yet.
The related Elvis operator ?: was proposed to make x ?: y shorthand for x != null ? x : y, especially useful when x is a complex expression.
This syntax does not exist in Java, nor is it slated to be included in any of the upcoming versions that I know of.
[EDIT]
Upon further thought, I figured out that it is actually possible to achieve the same only using standard Java 8 classes:
public String getFirstName(Person person) {
return Optional.ofNullable(person)
.map(Person::getName)
.map(Name::getGivenName)
.orElse(null);
}
In this case, it is even possible to choose a default value (like "<no first name>") instead of null by passing it as parameter of orElse.
[Original Answer]
One way to workaround the lack of "?" operator using Java 8 without the overhead of try-catch (which could also hide a NullPointerException originated elsewhere, as mentioned) is to create a class to "pipe" methods in a Java-8-Stream style.
public class Pipe<T> {
private T object;
private Pipe(T t) {
object = t;
}
public static<T> Pipe<T> of(T t) {
return new Pipe<>(t);
}
public <S> Pipe<S> after(Function<? super T, ? extends S> plumber) {
return new Pipe<>(object == null ? null : plumber.apply(object));
}
public T get() {
return object;
}
public T orElse(T other) {
return object == null ? other : object;
}
}
Then, the given example would become:
public String getFirstName(Person person) {
return Pipe.of(person)
.after(Person::getName)
.after(Name::getGivenName)
.get();
}
Java does not have the exact syntax but as of JDK-8, we have the Optional API with various methods at our disposal. So, the C# version with the use of null conditional operator:
return person?.getName()?.getGivenName();
can be written as follows in Java with the Optional API:
return Optional.ofNullable(person)
.map(e -> e.getName())
.map(e -> e.getGivenName())
.orElse(null);
if any of person, getName or getGivenName is null then null is returned.
There was a proposal for it in Java 7, but it was rejected:
http://tech.puredanger.com/java7/#null
See: https://blogs.oracle.com/darcy/project-coin:-the-final-five-or-so (specifically "Elvis and other null safe operators").
The result is that this feature was considered for Java 7, but was not included.
That's actually Groovy's safe-dereference operator. You can't use it in pure Java (sadly), so that post is simply wrong (or more likely slightly misleading, if it's claiming Groovy to be the "latest version of Java").
As lot of answers mentioned Java language don't have this feature.
It is possible in few scenarios with this compiler plugin, with few limitations
In the example code you mentioned can be written as
public String getFirstName(Person person) {
#NullSafe
String retVal = person.getName().getGivenName();
return retVal;
}
PS: I am author of plugin
It is possible to define util methods which solves this in an almost pretty way with Java 8 lambda.
This is a variation of H-MANs solution but it uses overloaded methods with multiple arguments to handle multiple steps instead of catching NullPointerException.
Even if I think this solution is kind of cool I think I prefer Helder Pereira's seconds one since that doesn't require any util methods.
void example() {
Entry entry = new Entry();
// This is the same as H-MANs solution
Person person = getNullsafe(entry, e -> e.getPerson());
// Get object in several steps
String givenName = getNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.getGivenName());
// Call void methods
doNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.nameIt());
}
/** Return result of call to f1 with o1 if it is non-null, otherwise return null. */
public static <R, T1> R getNullsafe(T1 o1, Function<T1, R> f1) {
if (o1 != null) return f1.apply(o1);
return null;
}
public static <R, T0, T1> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, R> f2) {
return getNullsafe(getNullsafe(o0, f1), f2);
}
public static <R, T0, T1, T2> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Function<T2, R> f3) {
return getNullsafe(getNullsafe(o0, f1, f2), f3);
}
/** Call consumer f1 with o1 if it is non-null, otherwise do nothing. */
public static <T1> void doNullsafe(T1 o1, Consumer<T1> f1) {
if (o1 != null) f1.accept(o1);
}
public static <T0, T1> void doNullsafe(T0 o0, Function<T0, T1> f1, Consumer<T1> f2) {
doNullsafe(getNullsafe(o0, f1), f2);
}
public static <T0, T1, T2> void doNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Consumer<T2> f3) {
doNullsafe(getNullsafe(o0, f1, f2), f3);
}
class Entry {
Person getPerson() { return null; }
}
class Person {
Name getName() { return null; }
}
class Name {
void nameIt() {}
String getGivenName() { return null; }
}
I'm not sure this would even work; if, say, the person reference was null, what would the runtime replace it with? A new Person? That would require the Person to have some default initialization that you'd expect in this case. You may avoid null reference exceptions but you'd still get unpredictable behavior if you didn't plan for these types of setups.
The ?? operator in C# might be best termed the "coalesce" operator; you can chain several expressions and it will return the first that isn't null. Unfortunately, Java doesn't have it. I think the best you could do is use the ternary operator to perform null checks and evaluate an alternative to the entire expression if any member in the chain is null:
return person == null ? ""
: person.getName() == null ? ""
: person.getName().getGivenName();
You could also use try-catch:
try
{
return person.getName().getGivenName();
}
catch(NullReferenceException)
{
return "";
}
There you have it, null-safe invocation in Java 8:
public void someMethod() {
String userName = nullIfAbsent(new Order(), t -> t.getAccount().getUser()
.getName());
}
static <T, R> R nullIfAbsent(T t, Function<T, R> funct) {
try {
return funct.apply(t);
} catch (NullPointerException e) {
return null;
}
}
If someone is looking for an alternative for old java versions, you can try this one I wrote:
/**
* Strong typed Lambda to return NULL or DEFAULT VALUES instead of runtime errors.
* if you override the defaultValue method, if the execution result was null it will be used in place
*
*
* Sample:
*
* It won't throw a NullPointerException but null.
* <pre>
* {#code
* new RuntimeExceptionHandlerLambda<String> () {
* #Override
* public String evaluate() {
* String x = null;
* return x.trim();
* }
* }.get();
* }
* <pre>
*
*
* #author Robson_Farias
*
*/
public abstract class RuntimeExceptionHandlerLambda<T> {
private T result;
private RuntimeException exception;
public abstract T evaluate();
public RuntimeException getException() {
return exception;
}
public boolean hasException() {
return exception != null;
}
public T defaultValue() {
return result;
}
public T get() {
try {
result = evaluate();
} catch (RuntimeException runtimeException) {
exception = runtimeException;
}
return result == null ? defaultValue() : result;
}
}
You can test the code which you have provided and it will give syntax error.So, it is not supported in Java.
Groovy does support it and it was proposed for Java 7 (but never got included).
However, you can use the Optional provided in Java 8. This might help you in achieving something on similar line.
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
Example Code for Optional
STEP-1 : Use this generic method.
public static <T> Optional<T> optionalChaining(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
} catch (NullPointerException e) {
return Optional.empty();
}
}
STEP-2 one example of usage of this method is below
Optional<String> rs = optionalChaining(()-> user.getName("Talha").getLastName());
if(rs.isPresent()) {
}
Done !!
Since Android does not support Lambda Functions unless your installed OS is >= 24, we need to use reflection.
// Example using doIt function with sample classes
public void Test() {
testEntry(new Entry(null));
testEntry(new Entry(new Person(new Name("Bob"))));
}
static void testEntry(Entry entry) {
doIt(doIt(doIt(entry, "getPerson"), "getName"), "getName");
}
// Helper to safely execute function
public static <T,R> R doIt(T obj, String methodName) {
try {
if (obj != null)
return (R)obj.getClass().getDeclaredMethod(methodName).invoke(obj);
} catch (Exception ignore) {
}
return null;
}
// Sample test classes
static class Entry {
Person person;
Entry(Person person) { this.person = person; }
Person getPerson() { return person; }
}
static class Person {
Name name;
Person(Name name) { this.name = name; }
Name getName() { return name; }
}
static class Name {
String name;
Name(String name) { this.name = name; }
String getName() {
System.out.print(" Name:" + name + " ");
return name;
}
}
}
If this is not a performance issue for you, you can write
public String getFirstName(Person person) {
try {
return person.getName().getGivenName();
} catch (NullPointerException ignored) {
return null;
}
}
Suppose I have this:
public class Unit<MobileSuit, Pilot> {
...
List<MobileSuit> mobileSuits;
List<Pilot> pilots;
...
}
And I would like to iterate through the pair of each in the simplest way outside of that class. How should I go about doing that? I thought about doing this:
public class Unit<MobileSuit, Pilot> {
...
Iterator<MobileSuit> iteratinMechas;
Iterator<Pilot> iteratinPeople;
class IteratorCustom<MobileSuit, Pilot> implements Iterator {
public boolean hasNext() {
return iteratinMechas.hasNext() && iteratinPeople.hasNext();
}
public void remove() {
iteratinMechas.remove();
iteratinPeople.remove();
}
public Object next() {
// /!\
}
}
public Iterator iterator() {
return new IteratorCustom<MobileSuit, Pilot>(mobileSuits, pilots);
}
}
Something along those lines.
Anyway, the problem is that I can't really return just a single object from next(), and I also can't have a Iterator take more than one type. So, any thoughts?
Also, I can't make a new class to combine MobileSuit and Pilot. I need to keep them separate, even though I'm iterating through both at a time. The reason is that there might be Mobile Suits that have no pilots, and I'm not sure how to fix that by keeping them at the same class. This class needs to be processed in other places, so I'd have to unify a interface around that and a lot of other stuff. Basically, assume MobileSuit and Pilot need to be separated.
Anyway, the problem is that I can't really return just a single object from next(), and I also can't have a Iterator take more than one type. So, any thoughts?
Obviously you are going to need a light-weight "pair" class. This is roughly analogous to the Map.Entry inner class.
Here's a rough cut at a generic solution:
public class ParallelIterator <T1, T2> implements Iterator<Pair<T1, T2>> {
public class Pair<TT1, TT2> {
private final TT1 v1;
private final TT2 v2;
private Pair(TT1 v1, TT2 v2) { this.v1 = v1; this.v2 = v2; }
...
}
private final Iterator<T1> it1;
private final Iterator<T2> it2;
public ParallelIterator(Iterator<T1> it1, Iterator<T2> it2) {
this.it1 = it1; this.it2 = it2;
}
public boolean hasNext() { return it1.hasNext() && it2.hasNext(); }
public Pair<T1, T2> next() {
return new Pair<T1, T2>(it1.next(), it2.next());
}
...
}
Note: this doesn't explicitly deal with cases where the lists have different lengths. What will happen is that extra elements at the end of the longer list will be silently ignored.
This is copied+edited from Stephen C's answer. Feel free to use:
public class Pair<T1, T2> {
private final T1 v1;
private final T2 v2;
Pair(T1 v1, T2 v2) {
this.v1 = v1;
this.v2 = v2;
}
public T1 first(){
return v1;
}
public T2 second(){
return v2;
}
}
public class ParallelIterator <T1, T2> implements Iterator<Pair<T1, T2>> {
private final Iterator<T1> it1;
private final Iterator<T2> it2;
public ParallelIterator(Iterator<T1> it1, Iterator<T2> it2) {
this.it1 = it1; this.it2 = it2;
}
#Override
public boolean hasNext() { return it1.hasNext() && it2.hasNext(); }
#Override
public Pair<T1, T2> next() {
return new Pair<T1, T2>(it1.next(), it2.next());
}
#Override
public void remove(){
it1.remove();
it2.remove();
}
}
public class IterablePair <T1, T2> implements Iterable<Pair<T1,T2>> {
private final List<T1> first;
private final List<T2> second;
public IterablePair(List<T1> first, List<T2> second) {
this.first = first;
this.second = second;
}
#Override
public Iterator<Pair<T1, T2>> iterator(){
return new ParallelIterator<T1,T2>( first.iterator(), second.iterator() );
}
}
void someFunction(){
IterablePair<X,Y> listPair = new IterablePair<X,Y>( x, y );
for( Pair<X,Y> pair : listPair ){
X x = pair.first();
...
}
}
This stops as soon as either list is out of elements, so you might want to check lists have equal size before creating an IterablePair.
Also, I can't make a new class to combine MobileSuit and Pilot.
That doesn't sound correct. It sounds like you can't replace MobileSuit and Pilot by a single class, but I don't see any reason why you can't have a single class that combines them - i.e. one which just has a getPilot() method and a getMobileSuit() method. You could use a generic Pair class for the same purpose, but a custom class would be easier to use.
On the other hand, if you want to do this sort of "zipping" operation in multiple places, it might be one solution. Alternatively, you could write a generic interface to represent the act of combining the two distinct items - which could return a SuitedPilot or whatever your combination class is.
The reason is that there might be Mobile Suits that have no pilots, and I'm not sure how to fix that by keeping them at the same class.
You can use null values, right? Which is the correct way of doing it - have each suit keep track of its pilot. If it has no pilot, then indicate that with a null value there.
But, if you're dead set on not doing that for some reason...
public class SuitAndPilot
{
public MobileSuit suit;
public Pilot pilot;
public SuitAndPilot(Suit s, Pilot p) {
suit = s;
pilot = p;
}
}
Why not have a class MannedMobileSuit as a subclass of MobileSuit that contains an instance of a pilot ? That would solve your problem by having a getPilot method.
Usually when you get such problems (needing to return two instances) it is because your Object model is not appropriate and should be changed. Keep your options open
Came across this page trying to solve this issue, and turns out that there's a library out there that's already solved it using Java 8 streams (check out the Zip function).
You can convert a list to a stream just by calling list.stream()
https://github.com/poetix/protonpack
Stream<String> streamA = Stream.of("A", "B", "C");
Stream<String> streamB = Stream.of("Apple", "Banana", "Carrot", "Doughnut");
List<String> zipped = StreamUtils.zip(streamA,
streamB,
(a, b) -> a + " is for " + b)
.collect(Collectors.toList());
assertThat(zipped,
contains("A is for Apple", "B is for Banana", "C is for Carrot"));
Basically, assume MobileSuit and Pilot need to be separated.
That's fine, but here you're trying to treat them as a unit, so structure your code that way. The suggestions above use a Pair class or Map.Entry, but it's much better to provide a clearly-named object that represents a MobileSuit with a Pilot, e.g.:
public class OccupiedSuit {
private final MobileSuit suit;
private final Pilot pilot;
public OccupiedSuit(MobileSuit suit, Pilot pilot) {
this.suit = checkNotNull(suit);
this.pilot = checkNotNull(pilot);
}
// getters, equals, hashCode, toString
// or just use #AutoValue: https://github.com/google/auto/tree/master/value
}
Then, rather than constructing a custom Iterator/Iterable, just write a helper function that zips up the two lists. For example:
public static List<OccupiedSuit> assignPilots(
Iterable<MobileSuit> suits, Iterable<Pilot> pilots) {
Iterator<MobileSuit> suitsIter = suits.iterator();
Iterator<Pilot> pilotsIter = pilots.iterator();
ImmutableList.Builder<OccupiedSuit> builder = ImmutableList.builder();
while (suitsIter.hasNext() && pilotsIter.hasNext()) {
builder.add(new OccupiedSuit(suitsIter.next(), pilotsIter.next()));
}
// Most of the existing solutions fail to enforce that the lists are the same
// size. That is a *classic* source of bugs. Always enforce your invariants!
checkArgument(!suitsIter.hasNext(),
"Unexpected extra suits: %s", ImmutableList.copyOf(suitsIter));
checkArgument(!pilotsIter.hasNext(),
"Unexpected extra pilots: %s", ImmutableList.copyOf(pilotsIter));
return builder.build();
}
Now you don't need to maintain a complex custom Iterator implementation - just rely on one that already exists!
We can also generalize assignPilots() into a generic utility that works for any two inputs, like so:
public static <L,R,M> List<M> zipLists(
BiFunction<L,R,M> factory, Iterable<L> left, Iterable<R> right) {
Iterator<L> lIter = left.iterator();
Iterator<R> rIter = right.iterator();
ImmutableList.Builder<M> builder = ImmutableList.builder();
while (lIter.hasNext() && rIter.hasNext()) {
builder.add(factory.apply(lIter.next(), rIter.next()));
}
checkArgument(!lIter.hasNext(),
"Unexpected extra left elements: %s", ImmutableList.copyOf(lIter));
checkArgument(!rIter.hasNext(),
"Unexpected extra right elements: %s", ImmutableList.copyOf(rIter));
return builder.build();
}
Which you'd then invoke like so:
List<OccupiedSuit> occupiedSuits = zipLists(OccupiedSuit::new, suits, pilots);
Example code uses Guava's Preconditions and ImmutableList - if you don't use Guava it's easy enough to inline and swap to ArrayList, but just use Guava :)
for(int i=0; i < mobileSuits.size(); i++) {
MobileSuit suit = mobileSuits.get(i);
Pilot pilot = pilots.get(i);
...
}
You could just use a Map<MobileSuit, Pilot>, where a null value mapped to a MobileSuit indicates no pilot. The Iterator could just be an Iterator<Map.Entry<MobileSuit, Pilot>> retrieved by map.entrySet().iterator().
Improving on the answer by user2224844, here is a simple version that will try no to run into an exception:
final Iterator<String> pilotIterator = pilots.iterator();
mobileSuits.forEach(m -> {
Pilot p = pilotIterator.hasNext()? pilotIterator.next():nullOrWahtever;
<Now do your work with m and p variables>
...
});
Isn't that enough ?
for(MobileSuit ms : MobileSuits) {
for(Pilot p : pilots){
//TODO
}
}