Updating method to remove loop - java

This is how I understand method getUser below :
Return a User object or null
Get a Set of users and assign them to userSer.
If the set is not empty begin iterating over the set but
return the first user within the set.
Here is the method :
private User getUser(UserDet arg)
{
Set<User> userSet = arg.getUsers(User.class);
if (CollectionUtils.isNotEmpty(userSet))
{
for (User user : userSet)
{
return user;
}
}
return null;
}
I think I could replace the method with this :
private User getUser(UserDet arg)
{
Set<User> userSet = arg.getUsers(User.class);
if (CollectionUtils.isNotEmpty(userSet))
{
return userSet.iterator().next();
}
else {
return null;
}
}
This new method removes the loop and just returns the first element in the set, same as original implemention. Is it correct?

Yes. Actually, it's pretty much almost the same thing, as a foreach loop is syntactic sugar for using an iterator from an Iterable.
Note, however, that you don't need the nonempty check in the first variant, since the loop won't iterate in the case of an empty set anyway.

yes both are same. in first implementation, control will return on first iteration of the loop from the function and consequently loop will end.

Yes it is correct, I'd even go for removing the CollectionUtils.isNotEmptySet and use the Iterator's hasNext method... If the set is guaranteed to be non-null.

It seems to be correct, but it will only make the method a bit easier to read, it will not optimize it in terms of performance. Still I think the change is good and you should do it.

Yes, it does pretty much the same, but if your spec says to start iterating then maybe you should - maybe this method will be extended in the future.
BTW: it is a good convention that your method has only one return statement (i.e. you can create a variable, which will be returned, assigned a null at the beginning and assign a user inside your loop)

Yes. Both the methods return the first element in the set. The first method seems to have been written for something else previously and changed then keeping the for loop intact.
In anycase, the second method that you're proposing won't give any significant performance benefit but should be a better way than the first one.

So in case, UserDet#getUsers(Class) never returns null (but an empty Set in case no user could be found), the shortest (and in my opinion most readable) form is:
private User getUser(UserDet arg) {
Set<User> userSet = arg.getUsers(User.class);
return userSet.isEmpty() ? null : userSet.iterator().next();
}

I would do this.
I won't run a loop and more over I'l add a null check.
private User getUser(UserDet arg) {
Set<User> userSet = arg.getUsers(User.class);
if (userSet != null && userSet.size() > 0) {
return userSet.iterator().next();
}
return null;
}

Related

How to check if a java method returns null without having to run it twice

I have this situation many times in my code,
I have a method for example such as:
private Object doSomething(){
//Do something
doSomething ? return Object : return null;
}
This is just an example, then in the main body of my code I need to check that this doesn't return null before I do something else. For example:
if(doSomething() != null){
Object object = doSomething();
From a performance perspective this method is being asked to run twice, once to check it doesn't return null and next to assign the new variable as long as it returns a valid object.
Is there a way to develop this code where this double running doesn't have to take place. Bearing in mind that the check to make sure the object is valid is important in the code.
Just reverse the process. First assign the result of that call to a variable, then check if the variable is null.
Object object = doSomething();
if (object != null) {
// do whatever with object
} else {
// do something else
}
It is worth noting that the problem with multiple calls to doSomething may not only be a performance penalty. It could also be a problem if:
doSomething has side effects, for example if it inserts a row in a database, in which case calling it twice will insert two rows.
doSomething depends on some external state which may change between invocations.
Consider using Optional rather than returning null (introduced with Java 8).
public Optional<Object> doSomething() {
return Optional.ofNullable(someData);
}
When invoked, you have an Optional reference that may (or may not) have contents.
Optional<Object> maybeSomething = doSomething();
if (maybeSomething.isPresent()) {
Object someData = maybeSomething.get();
System.out.println("SomeData = "+someData);
}
Optional blends well with lambda so you could rewrite that as..
Optional<Object> maybeSomething = doSomething();
maybeSomething.ifPresent(someData -> System.out.println("SomeData = " + someData);
or, if you don't need to do more work with someData you could even do
doSomething().ifPresent(someData -> System.out.println("SomeData = " + someData);

Validating order of method call

A class named OutgoingItems has 2 methods: getNextItem() and hasItems() .
In the current implementation getNextItem() is getting into a endless loop if hasItems() == true.
Is there a way to validate in the code that this method is not being called unless the condition for hasItems() == true has been checked first?
Maybe some sort of relevant annotation for static analysis?
Assume that implementation changing is hard and there's a change that one can't just do it.
What you describe sounds semantically weird, surely calling getNextItem() doesn't make sense unless hasItems() is true?
Anyway, the idea is the same, whichever way your logic works: wrap your OutgoingItems objects into a new class that checks the condition for you. I did the check with assert but you can choose whatever way you like.
public class OutgoingItemsDelegate {
private final OutgoingItems items;
public OutgoingItemsDelegate(OutgoingItems items) {
this.items = items;
}
public boolean hasItems() {
return items.hasItems();
}
public Object getNextItem() {
assert !items.hasItems();
// alternatively you can do this:
// if (items.hasItems()) throw new IllegalStateException("hasItems() must not be true");
return items.getNextItems();
}
}
There is of course a slight performance and space overhead you might have to pay with this solution, and the ideal solution is to fix OutgoingItems itself, but failing that, it's a viable option.
*Please note that for the assert statement to be evaluated, you need to use the -ea flag on the command line.

Is it a good practice to return a boolean/value instead of null in case of no-ops?

This observation was made after looking at addNode code in DirectedGraph.java. The coder has used a true and a false to distinguish a no-op from an op. A similar example is the code below custom made simply to ask my question easily. Is it a recommended / good practice to return boolean to differentiate and no-op from an op to give more visibility to the client of code ?
public class FreeMain {
private List<Integer> fooList;
FreeMain ( ) { }
/**
* Lazy init - either set a value of no-op.
*
* #param barList
*/
public void putList(List<Integer> barList) {
if (this.fooList == null) {
this.fooList = barList;
}
}
/**
* Boolean returned as an indication to the user of operation status
*
* #param barList
* #return true if putLists sets the value, false is no-op.
*/
public boolean putListWithBoolean(List<Integer> barList) {
if (this.fooList == null) {
this.fooList = barList;
return true;
}
return false;
}
}
I will set it this way, is the responsibillity of the putList in this case to tell you whether the list you try to put is accepted or not by returning a boolean? In my opinion no, this is because the putList should handle only the single module of replacing the list pointer and not return something.
If you actually want to know whether the conditions are granted or not(or for any ubnormal behavior that could occur), use Exceptions. Then simply catch those exceptions into your main when the putList is used(with try-catch blocks) and do whatever you wish.
For example:
public void putList(List<Integer> barList) throws new MyListException{
if (this.fooList == null) {
this.fooList = barList;
} else {
throw new MyListException("The pointer of fooList can not be changed because the fooList is not null");
}
}
public class MyListException extends Exception {
public MyListException(String s) {
super(s);
}
}
On the other hand, the case that the method would return a true/false is when it should actually handle that module and determine whether a list will be accepted or not by testing the condition. Thus, the method name will be 'isListAccepted()' (a parameter is not needed since it doesnt play any role). However, in java it is noticed (i.e See LinkedList click here) that sometimes methods like public boolean add(E e) returns true/false. This is because those methods are implemented under the collection interface and there are some preconditions in the way the collection works. Additionally, in this case as well oracle documentation says:
public boolean add(E e) Ensures that this collection contains the specified element
(optional operation). Returns true if this collection changed as a result of the
call. (Returns false if this collection does not permit duplicates and
already contains the specified element.)
If a collection refuses to add a particular element for any reason
other than that it already contains the element, it must throw an
exception (rather than returning false).
So based on that, I believe that these operations, handle the module of telling you if your collection has changed or not after their use rather than adding the element(even if they do in some cases).
An example:
private boolean isListAccepted() {
return this.fooList == null;
}
Finally, since I am not sure too about what do you mean with "instead of null in case of no-operations", I am gonna say that: when you use the putList(..) and the condition is not granted, it doesnt return null, but rather it is doing nothing. However, it is always preferable in this case as well to use Exceptions as I already demonstrate(in the first example) so that you will know what went wrong in case you expect the putList() to actually replace the pointer. And this is because you wont always have the chance to spend time searching the code to understand what went wrong. This is not really important with the code example you provided since it is simple but what if you had a putList that was more complex and multiple things could go wrong ?
Overall, i can not say if putListWithBoolean() is a bad practice because it depends on the way it is used(as shown with the java example), while the putList() without exceptions can be considered as a bad practice, because your classes wont be that simple always, and many things could go wrong, so you better know what went wrong and where.

Need help stepping through a java iterator

Say I have already created an iterator called "iter" and an arraylist called "database". I want to be able to look through the arraylist and see if any element in the arraylist is equal to a String called "test". If it is, then I would like to add the element to another list.
while(iter.hasNext()) {
if(database.next() == test) {
database.next().add(another_list);
}
}
What am I doing wrong? I'm completely new to iterators in java. Do I need to write my own iterator class? Any code examples would be greatly appreciated. Thanks
The problem with your code is that every time you call .next(), it advances the iterator forward to the next position. This means that this code
if(database.next() == test) {
database.next().add(another_list);
}
Won't work as intended, because the first call to database.next() will not give back the same value as the second call to database.next(). To fix this, you'll want to make a temporary variable to hold on to the new value, as seen here:
while(iter.hasNext()) {
/* type */ curr = iter.next();
if(curr == test) {
curr.add(another_list);
}
}
(Filling in the real type of what's being iterated over in place of /* type */)
In many cases, though, you don't need to use iterators explicitly. Most of the Collections types implement the Iterable interface, in which case you can just write
/* container */ c;
for(/* type */ curr: c) {
if(curr == test) {
curr.add(another_list);
}
}
Hope this helps!
if(database.contains("test"))
{
another_list.add("test");
}
you can use the built in method contains(...)
you should use equals(...) for data comparisions
look at the javadoc to see if there is already a method present for your purpose

Google Collections Suppliers and Find

I'm looking for a Google Collections method that returns the first result of a sequence of Suppliers that doesn't return null.
I was looking at using Iterables.find() but in my Predicate I would have to call my supplier to compare the result against null, and then have to call it again once the find method returned the supplier.
Given your comment to Calm Storm's answer (the desire not to call Supplier.get() twice), then what about:
private static final Function<Supplier<X>, X> SUPPLY = new Function<....>() {
public X apply(Supplier<X> in) {
// If you will never have a null Supplier, you can skip the test;
// otherwise, null Supplier will be treated same as one that returns null
// from get(), i.e. skipped
return (in == null) ? null : in.get();
}
}
then
Iterable<Supplier<X>> suppliers = ... wherever this comes from ...
Iterable<X> supplied = Iterables.transform(suppliers, SUPPLY);
X first = Iterables.find(supplied, Predicates.notNull());
note that the Iterable that comes out of Iterables.transform() is lazily-evaluated, therefore as Iterables.find() loops over it, you only evaluate as far as the first non-null-returning one, and that only once.
You asked for how to do this using Google Collections, but here's how you would do it without using Google Collections. Compare it to Cowan's answer (which is a good answer) -- which is easier to understand?
private static Thing findThing(List<Supplier<Thing>> thingSuppliers) {
for (Supplier<Thing> supplier : thingSuppliers) {
Thing thing = supplier.get();
if (thing != null) {
return thing;
}
}
// throw exception or return null
}
In place of the comment -- if this was the fault of the caller of your class, throw IllegalArgumentException or IllegalStateException as appropriate; if this shouldn't have ever happened, use AssertionError; if it's a normal occurrence your code that invokes this expects to have to check for, you might return null.
What is wrong with this?
List<Supplier> supplierList = //somehow get the list
Supplier s = Iterables.find(supplierList, new Predicate<Supplier>(){
boolean apply(Supplier supplier) {
return supplier.isSomeMethodCall() == null;
}
boolean equals(Object o) {
return false;
}
});
Are you trying to save some lines? The only optimisation I can think is to static import the find so you can get rid of "Iterables". Also the predicate is an anonymous inner class, if you need it in more than one place you can create a class and it would look as,
List<Supplier> supplierList = //somehow get the list
Supplier s = find(supplierList, new SupplierPredicateFinder());
Where SupplierPredicateFinder is another class.
UPDATE : In that case find is the wrong method. You actually need a custom function like this which can return two values. If you are using commons-collections then you can use a DefaultMapEntry or you can simply return an Object[2] or a Map.Entry.
public static DefaultMapEntry getSupplier(List<Supplier> list) {
for(Supplier s : list) {
Object heavyObject = s.invokeCostlyMethod();
if(heavyObject != null) {
return new DefaultMapEntry(s, heavyObject);
}
}
}
Replace the DefaultMapEntry with a List of size 2 or a hashmap of size 1 or an array of length 2 :)

Categories

Resources