How to implement the below feature using java8 - java

How to implement this in java8 and anyone please help me,i tried using streams but not working may be syntactically i was wrong.
I have tried:
list.stream().map(res->.get(s)).filter(res->res!=null && res.equalIgnoreCase("something"))

You can use a new java8 Collection.removeIf() method. The method works by applying the condition provided in the Predicate instance to all the elements in the Collection on which it is invoked. The elements which satisfy the condition are retained while the remaining are removed from the Collection.
list.removeIf(item -> {
String res = map.get(item);
return res != null && res.equalsIgnoreCase("smt");
});

Related

How effectively we can code null checks Java 8

Little new to Java 8 style;
How effectively, we can code for the below statement by including all the null checks usin Java 8 API
search.getResource()
.getResults().get(0).getCustomer().getPhoneNumber()
I tried like following: (Looks little weird to me with Optional everywhere)
List<Result> results = search.getResource().getResults();
Optional<Result> optionalResult = Optional.of(results).orElse(new ArrayList<>()).stream().findFirst();
if(optionalResult.isPresent() && Optional.of(optionalResult.get().getCustomer()).isPresent()) {
Source source = Optional.of(optionalResult.get().getCustomer()).get();
Optional<List<Customer>> customers = Optional.of(source.getCustomers());
if(customers.isPresent() && customers.get().stream().findFirst().isPresent() &&
Optional.of(customers.get().stream().findFirst().get().getPhoneNumber()).isPresent())
dest.setNumber(Integer.parseInt(customers.get().stream().findFirst().get().getPhoneNumber())));
}
Could you please suggest me a better way of doing. Thanks!
You can use the map method of Optional class:
final Optional<String> optional = Optional.ofNullable(search.getResource())
.map(resource -> resource.getResults())
.map(results -> results.size() > 0 ? results.get(0) : null)
.map(result -> result.getCustomer())
.map(customer -> customer.getPhoneNumber());
optional.ifPresent(phoneNumber -> {
System.out.println(phoneNumber);
});
OT: Why don't you simply code null safe?
Coding null safe means that you never explicitly retun a (literal) null from a method or pass one in as a parameter. Furthermore you always do you null checks on local variables before you pass them around or return them.
On Map collections you use getOrDefault or computeIfAbsent to replace the null returned for missing keys with a Null Equivalent Constant of the expected type.
Usually passing null back and forth is a in band signal for an error condition which Java has exceptions for.
And no: passing around Optional is not a solution, but another incarnation of the problem. Optional is an elegant way to deal with variables than may contain null within a method.
Don't let it escape...

Java 8 lambda expression is present

First I need to check if data is present in list then get else set default or empty value on a Java 8 stream.
Currently I am using below code without isPresent but I dont know how to use isPresent in java8.
I am trying something below which is not perfect:
String isScheme = (this.mapProgramApproaches.stream().findFirst().isPresent())? this.mapProgramApproaches.stream().findFirst().get().getIsScheme().toString() : "0";
Where as mapProgramApproaches this is set.
Don't use isPresent() (it makes no sense to run the Stream pipeline twice).
You can use map to map the value of the Optional to the required String, and then
use orElse() to return a default value when the Optional value is not present:
String isScheme = this.mapProgramApproaches.stream()
.findFirst()
.map(o->o.getIsScheme().toString())
.orElse("0");
Maybe you are looking for something like this:
String isScheme = this.mapProgramApproaches.stream()
.findFirst()
.map(p -> p.getIsScheme().toString())
.orElse("0");
I'm not sure about context in which you are doing this, but I suppose that you would like to check whether some object is scheme and then do something with that. In that case I would suggest implement it like this:
List<String> mapProgramApproaches = new ArrayList<>();
mapProgramApproaches.stream()
.filter(this::isScheme)
.findFirst()
.ifPresent(this::doYourCode)
.orElse(defaultValue);
It will make your code cleaner. And will help to avoid additional conditionals!

Can Java 8 Streams use multiple items from mapping pipeline

I have some data stored in a JPA Repository that I am trying to process. I would like to be able to use Java 8 Streams to do so, but can not figure out how to get the required information. This particular 'Entity' is actually only for recovery, so it holds items that would need to be processed after something like a power-fail/restart.
Using pre-Java 8 for-loops the code would look like:
List<MyEntity> deletes = myEntityJpaRepository.findByDeletes();
for (MyEntity item : deletes) {
String itemJson = item.getData();
// use a Jackson 'objectMapper' already setup to de-serialize
MyEventClass deleteEvent = objectMapper.readValue(itemJson, MyEventClass.class);
processDelete(deleteEvent, item.getId());
}
The problem arises from the two parameter method called at the very end. Using Streams, I believe I would do:
// deletes.stream()
// .map(i -> i.getData())
// .map(event -> objectMapper.readValue(event, MyEventClass.class))
// .forEach(??? can't get 'id' here to invoke 2 parameter method);
I have a solution (without Streams) that I can live with. However I would think this problem comes up a lot, thus my question is: IN GENERAL, is there a way using Streams to accomplish what I am trying to do?
Why not a Pair return on your map operation:
.map(i -> new Pair<>(i.getData(), i.getId()))
.map(pair -> new Pair<>(objectMapper.readValue(pair.getLeft(), MyEventClass.class), pair.getRight())
.forEach(p -> processDelete(pair.getLeft(), pair.getRight()))
I did not compile this, so there might be minor things to fix. But in general, you would need a Holder to pass your objects to the next stage in such a case. Either a Pair or some type or even a array.
Why not doing it simply this way?
deletes.forEach(item ->
processDelete(objectMapper.readValue(item.getData(), MyEventClass.class),
item.getId()));
This is a start at least, I guess it is dependent on why you want to use stream and how much you want to make it more functional
List<MyEntity> deletes = myEntityJpaRepository.findByDeletes();
deletes.stream().foreach(item -> {
String itemJson = item.getData();
// use a Jackson 'objectMapper' already setup to de-serialize
MyEventClass deleteEvent = objectMapper.readValue(itemJson, MyEventClass.class);
processDelete(deleteEvent, item.getId());
});

Java, search for an element, if not found, add it

I am pretty new to streams.
I would like to stream the geometries EC_Geometry arraylist and if the EC_Geometry element is not present (or better equals never returns true), then I add it.
public void init(GL3 gl3, EC_Mesh mesh) {
geometries.stream()
.filter(geometry -> mesh.getGeometry().equals(geometry))
.findAny()
.orElse(..?);
}
But I am stuck at the last line
How can I solve it using streams?
Please note that equals is a method I wrote checking if the geometry is the same (i.e: if the triangles correspond)
orElse will always run even if the value returned isn't used so it is preferable to use orElseGet here which will only run if nothing is found.
geometries.stream()
.filter(geometry -> mesh.getGeometry().equals(geometry))
.findAny()
.orElseGet(() -> {
geometries.add(mesh.getGeometry());
return mesh.getGeometry();
});
.findAny().orElse(..?);
is for Optional - if you would like to get first element found.
For what you would like to achieve the best approach would be just to:
meshG = mesh.getGeometry();
if (!geometries.contains(meshG)) {
geometries.add(meshG);
}
No need to overuse Stream API.

Guava: ImmutableSet of either values or an empty set

I need a cleaner solution to using an ImmutableSet. I have code that looks like
Set foo = ImmutableSet.copyOf(aGeoR.getFailed());
it works great when aGeoR.getFailed() returns one or more entries.
it fails when the returned set is null.
When its null, I need a
Set foo = ImmutableSet.of();
What is the clean way to do this?
This is phrased as a question about Guava and ImmutableSet, but the real issue here is with aGeoR.getFailed(). It is essentially never appropriate for a collection-returning method to return null. It should be returning an empty set to begin with (see Effective Java); and yeah, the fact that it isn't is going to cause some pain to users.
When I have to deal with an API like that, and I can't fix it or get it fixed, I do exactly what you showed in your revision of #Jherico's answer.
Set<FailedGeoR> failedOrNull = aGeoR.getFailed();
Set<FailedGeoR> failed = (failedOrNull == null)
? ImmutableSet.<FailedGeoR>of()
: ImmutableSet.copyOf(failedOrNull);
Set foo = aGeoR.getFailed();
foo = foo == null ? new HashSet() : ImmutableSet.copyOf(foo);
I would use an Optional:
Set<FailedGeoR> foo = Optional.ofNullable(aGeoR.getFailed())
.map(ImmutableSet::copyOf)
.orElse(ImmutableSet.of())
I agree #Agustín Ranieri, but if possible, I hope Guava add ofNull and copyOfNull methods, like Optional, and it's just do one more thing, when element is null or empty, always return ImmutableSet.of(), it's let me write less duplicates code.
// the foo always not be null
ImmutableSet<?> foo = ImmutableSet.copyOfNull(aGeoR.getFailed());

Categories

Resources