Return method reference - java-8

I am playing around in Java 8. How can I return a method reference?
I am able to return a lambda but not the method reference.
My attempts:
public Supplier<?> forEachChild(){
return new ArrayList<?>::forEach;
}
OR
public Function<?> forEachChild(){
return new ArrayList<?>::forEach;
}

You have a small mis-understanding of how method-references work.
First of all, you cannot new a method-reference.
Then, let's reason through what you want to do. You want the method forEachChild to be able to return something that would accept a List and a Consumer. The List would be on which object to invoke forEach on, and the Consumer would be the action to perform on each element of the list. For that, you can use a BiConsumer: this represents an operation taking 2 parameters and returning no results: the first parameter is a list and the second parameter is a consumer.
As such, the following will work:
public <T> BiConsumer<List<T>, Consumer<? super T>> forEachChild() {
return List::forEach;
}
This type of method-reference is called "Reference to an instance method of an arbitrary object of a particular type". What happens is that the first parameter of type List<T> becomes the object on which forEach will be invoked, by giving it as parameter the Consumer.
Then you can use it like:
forEachChild().accept(Arrays.asList("1", "2"), System.out::println);

I would like to add some points.
You can't instantiate unbounded type instance.
List<?> list = new ArrayList<?>();
Second, as Tunaki mentioned, you can't make references to new MyObject::staticMethod when you make method references
The other thing is, forEach(Consumer<T> consumer) (Terminal operation for pipeline streams) doesn't return anything. It only eats whatever we feed it.
-Hope this may help :)

Related

Spring-AOP Return value of Aspect #AfterReturn is not working

#AfterReturning(value = "anyPublicMethod() && applyPrivacy()", returning = "result")
public Object afterReturning(JoinPoint joinPoint, Object result) {
return someService.createNewObjectWithHelpOfResult(result);
}
My intention was to fill some null values in result fields. So in method createNewObjectWithHelpOfResult I'm creating a new Object and setting only the required values. But return value is not reflecting after afterReturning method is finished. But if I do mutations on result. They're very well reflected after aspect #AfterReturning method ends, but I want the return value to be used? Is this not possible? I'll have to do mutation only?
What #M.Deinum explained, is documented in the Spring manual, section "After Returning Advice". The end of the section reads:
Please note that it is not possible to return a totally different reference when using after returning advice.
Therefore, you cannot just make your #AfterReturning advice have a return type other than void and hope it will magically return something. As the advice type name implies, all 3 types of #After* advices run after the method has returned already. There is nothing you can do to change the result (except for altering internal state of an object instance). You can merely read (and e.g. log) it.
The solution, like #M.Deinum said, is an #Around advice, see also again the Spring manual.
It is generally a good idea to at least study the manual and learn some basics or take a look at examples before asking questions in public. I am sure you did not find any valid example for an #After* advice with non-void return type.
I am using #AfterReturning on the methods whose return type is String but instead of String I am getting null as result
#AfterReturning(value = "execution(* com.example.demo.aop.business..(..))", returning = "result")
public void afterA(JoinPoint joinPoint, Object result) {
log.info("After method {} returned with value {}", joinPoint, result);
}
O/P - After method execution(void com.example.demo.aop.business.Business2.disp()) returned with value null

Return an item by id

I got this piece of code, I am learning from tutorial. I want to return an element by url which looks like clients/1 instead of clients?id=1. How can I achieve this? Also, can the code below be made easier way?
#GetMapping
public Client getClient(#RequestParam int id) {
Optional<Client> first = clientList.stream().filter(element -> element.getId() == id).findFirst();
return first.get();
}
You may want to use #PathVariable as follows:
#Controller
#RequestMapping("/clients")
public class MyController {
#GetMapping("/{id}")
public Client getClient(#PathVariable int id) {
return clientList.stream().filter(element -> element.getId() == id).findFirst().orElseThrow();
}
Please note, the Optional can be unpacked with orElseThrow method. This will throw a NoSuchElementException in case there is no element found for the id.
Other solution would be to use orElse(new Client(...)) to return a default value if nothing is found.
get() is not really recommended to be used. From the JavaDoc of the get() method:
API Note:
The preferred alternative to this method is orElseThrow().
Even though get() may also throw a NoSuchElementException, similar to orElseThrow, usually the consensus is that get should not be used without isPresent, or should not be used at all. There several other methods to unpack the Optional without forcing you write an if.
The whole idea of the Optional is to overcome this by forcing you to think about the case when there is no value inside.

Pass optional objects as varags in parameter?

I want to pass multiple optional objects in function as varags ?
Optional<ab> ab = Optional.of(ab);
Optional<cd> cd = Optional.of(cd);
Optional<dc> dc = Optional.of(dc);
Optional<ba> ba = Optional.of(ba);
data(ab, cd, dc, ba);
data(Optional<Object>... objects){...}
I am getting error if i don this, any suggestion how can be proceed?
It isn’t related to varargs. You can’t pass an Optional<SomeSpecificType> where an Optional<Object> is expected. They are not compatible.
Assume just (without varargs):
static void data(Optional<Object> object) {
// …
}
Now if we try
Optional<String> ab = Optional.of("");
data(ab);
In my Eclipse I get this error message:
The method data(Optional<Object>) in the type MyClass is not
applicable for the arguments (Optional<String>)
Java generics are defined with this restriction. You also cannot pass, for example a List<String> where a List<Object> is expected.
You can overcome the limitation by declaring the method generic too:
static <T> void data(Optional<T> object) {
// …
}
Or just like this:
static void data(Optional<?> object) {
// …
}
With any of these two declarations the call above is OK.
BTW, #HadiJ is correct in the comment: Optional is meant for return values for from methods that may or may not be there. They have very few other good uses, and as parameters is not one of them. It seems to me that for your use case you should just pass the arguments that are there and leave out those that aren’t. The your data method may receive a longer or shorter argument array, but will just have to handle all elements of the array without caring about Optional. And passing String, Integer, LocalDate, etc, to a method declared void data(Object... objs) is straightforward and poses no problem.

Determining if all items in a collection meet established critera

This seems to be a problem that comes up a lot. I've been coming up with the same solution nearly every time but was curious if people have a better method of accomplishing this.
I have one class that is a list of instances of another class. The state of the parent class is dependent upon state of ALL the children
As an example. Say I have the following classes
class Box
{
int _objectId= <insert_unique_id>;
int _itemCount = 0;
public void AddItem()
{
_itemCount = Max(_itemCount + 1, 5);
}
public int GetId()
{
return _objectId;
}
public bool IsFull()
{
return _itemCount == 5
}
}
class BiggerBox
{
Map<int, Box> _boxes;
public void AddToBox(int id)
{
_boxes[id].AddItem();
}
public bool IsFull()
{
foreach(var box in _boxes.Values)
if(!box.IsFull())
return false;
return true;
}
}
All additions to a "Box" are done via the BiggerBox.AddToBox call. What I would like to do is be able to determine box.IsFull() without iterating over every single item every time we add an element.
Typically i accomplish this by keeping a SET or a separate collection of what items are full.
Curious, has anyone come up to an ingenious solution to this or is the simple answer that there is no other way?
There are two things you need to do in order to accomplish what you want:
Be able to control every entrypoint to your collection
React to changes to the objects in the collection
For instance, if the objects in the collection are mutable (meaning, they can change after being added to your collection) you need your main object to react to that change.
As you say, you could create a separate set of the objects that are full, but if the objects can change afterwards, when they change you either need to take them out of that set, or add them to it.
This means that in order for you to optimize this, you need some way to observe the changes to the underlying objects, for instance if they implement INotifyPropertyChanged or similar.
If the objects cannot change after being added to your main object, or you don't really care if they do, you just need to control every entrypoint, meaning that you basically need to add the necessary checks to your AddItem method.
For your particular types I would implement an event on the Box class so that when it is full, it fires the event. Your BiggerBox class would then hook into this event in order to observe when an underlying box becomes full.
You can upkeep the number of complete (or non-complete) boxes in BiggerBox class, and update it in all the functions.
E.g., in AddToBox it could be:
bool wasFull = _boxes[id].IsFull;
_boxes[id].AddItem();
if (!wasFull && _boxes[id].IsFull) // After this update box has become full.
completeBoxes += 1;
It is also possible to implement this upkeep procedure in other hypothetical functions (like RemoveFromBox, AddBox, RemoveBox, etc.)

Is there any way to clean up the following generic method using any of the new C# 4 features?

I've just modified a method for handling my DDD commands (previously it had no return type):
public static CommandResult<TReturn> Execute<TCommand, TReturn>(TCommand command)
where TCommand : IDomainCommand
{
var handler = IoCFactory.GetInstance<ICommandHandler<TCommand, TReturn>>();
return handler.Handle(command);
}
The method is fine, and does what I want it to do, however using it creates some fugly code:
CommandResult<Customer> result =
DomainCommands.Execute<CustomerCreateCommand, Customer>
(
new CustomerCreateCommand(message)
);
Before I added the Customer return type TReturn, it was nice and tidy and the method could infer the types from its usage. However that's no longer possible.
Is there any way using any new C# features that I could rewrite the above to make it tidier, i.e. using Func, Action, Expression, etc? I'm probably expecting the impossible, but I'm getting fed up of writing so much code to just call a single method that used to be very simple.
One option to reduce it slightly is to have a static generic type for the type parameter that can't be inferred, allowing you to have a generic method with just one type parameter that can be inferred:
public static class DomainCommands<TReturn>
{
public static CommandResult<TReturn> Execute<TCommand>(TCommand command)
where TCommand : IDomainCommand
{
var handler = IoCFactory.GetInstance<ICommandHandler<TCommand, TReturn>>();
return handler.Handle(command);
}
}
Then:
var result = DomainCommands<Customer>.Execute(new CustomerCreateCommand(msg));
It's not much nicer, but it's slightly better. Of course, if the domain command type itself could be generic, that might help - so CustomerCreateCommand would implement IDomainCommand<Customer> for example. If you still needed a nongeneric IDomainCommand, you could make IDomainCommand<T> derive from IDomainCommand.

Resources