Ways to check if an ArrayList contains only null values - java

I was looking through the code for an old Android application of mine, and I saw one thing I did to the effect of this:
boolean emptyArray = true;
for (int i = 0; i < array.size(); i++)
{
if (array.get(i) != null)
{
emptyArray = false;
break;
}
}
if (emptyArray == true)
{
return true;
}
return false;
There has to be a more efficient way of doing this -- but what is it?
emptyArray is defined as an ArrayList of Integers, which are inserted with a random number of null values (And later in the code, actual integer values).
Thanks!

Well, you could use a lot less code for starters:
public boolean isAllNulls(Iterable<?> array) {
for (Object element : array)
if (element != null) return false;
return true;
}
With this code, you can pass in a much wider variety of collections too.
Java 8 update:
public static boolean isAllNulls(Iterable<?> array) {
return StreamSupport.stream(array.spliterator(), true).allMatch(o -> o == null);
}

There is no more efficient way.
The only thing is you can do, is write it in more elegant way:
List<Something> l;
boolean nonNullElemExist= false;
for (Something s: l) {
if (s != null) {
nonNullElemExist = true;
break;
}
}
// use of nonNullElemExist;
Actually, it is possible that this is more efficient, since it uses Iterator and the Hotspot compiler has more info to optimize instead using size() and get().

It's not detection of contains only null values but it maybe be enough to use just contains(null) method on your list.

Simply Check it worked for me. Hope will work fine for you too!
if (arrayListSubQues!=null){
return true;}
else {
return false }

I use to do something like this :
// Simple loop to remove all 'null' from the list or a copy of the list
while array.remove(null) {
array.remove(null);
}
if (CollectionUtils.isEmpty(array)) {
// the list contained only nulls
}

Related

Recursive implementation of a method

I'm new to Java and still trying to wrap my head around recursion.The function below returns true at the very first intersection between the two sorted lists list x and list y.
public static boolean checkIntersection(List<Integer> x, List<Integer> y) {
int i = 0;
int j = 0;
while (i < x.size() && j < y.size()) {
if (x.get(i).equals(y.get(j))) {
return true;
} else if (x.get(i) < y.get(j)) {
i++;
} else {
j++;
}
}
return false;
}
Now I've been trying to implement it using recursion instead, and I know that there should be a base case which is an empty list in this case and then try to reduce the list by excluding one element at a time and feed it back to the same recursive function, but I can't work out how to check for intersection as I pass the rest of the list over and over.
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0){
return false;
}
else {
return recursiveChecking(x.subList(1, x.size()-1), y);
}
}
Any help would be highly appreciated. Thank you.
General approach to making something recursive is to think of two things:
When can I produce an answer trivially? - An answer to this question lets you code the base case. In your situation, you can produce the answer trivially when at least one of two lists is empty (the result would be false) or the initial elements of both non-empty lists are the same (the result would be true)
How do I reduce the problem when the answer is non-trivial? - An answer to this question lets you decide how to make your recursive call. In your case you could, for example, remove the initial element of one of the lists before making the recursive call*, or pass ListIterator<Integer> in place of List<Integer> for a non-destructive solution.
*Of course in this case you need to take care of either adding your numbers back after the call, or make a copy of two lists before starting the recursive chain.
As the lists are ordered, your recursion should remove the first element of the list with the smaller first value. Then you have to return true, if both lists start with the same number and false if any of the lists is empty. Otherwise you keep removing elements. This would look something like this (This code is untested):
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0 || y.size() == 0){
return false;
} else if (x.get(0).equals(y.get(0))) {
return true;
} else {
if (x.get(0) < y.get(0)) {
return recursiveChecking(x.subList(1, x.size()-1), y);
} else {
return recursiveChecking(x, y.subList(1, y.size()-1));
}
}
}

Missing a return statement somewhere?

I'm working on a basic Java assignment for school. This snippet involves searching for a specific part number in an ArrayList. When I try to compile, the IDE says I have a missing return statement. However, I can't see where it is. Do I need a return statement following the increment of the index? If so, then the return null becomes unreachable. Thank you guys very much.
public InventoryItem findInventoryItem(int searchPartNumber)
{
int index = 0;
boolean searching = true;
while (index < items.size() && searching){
InventoryItem inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if(fetchedPartNumber == (searchPartNumber)){
searching = false;
return inventoryItem;
}
else{
index++;
}
if(searching){
return null;
}
}
}
your code has several problems:
after you compared first item in list and it does not match - you will stop comparing, as searching is true and you will return null
in case of empty list you need to return null too
here is the fixed version:
public InventoryItem findInventoryItem(int searchPartNumber) {
for (InventoryItem inventoryItem : items)
if (inventoryItem.getPartNumber() == searchPartNumber)
return inventoryItem;
return null;
}
The method expected a return value in all cases. This means you have to add a return value in the else-block, too. Or you could add a return value only once at the end of all statements.
you're not handling the case where search will not be true.
That is,
if(searching){
return null;
}
Where is the else part handled here?
No matter what happens in your method, there has to be some value returned (even if it is null).
Right now, if you never get into your while (because that condition isn't fulfilled to begin with -> like when items.size() is 0), your method won't return anything.
In other words: Put a return null; after the closing bracket of your while loop.
Another important note: You do realize that this while will always only look at the first item, right? Because if your first item is not the one you're searching for, your variable searching will still be true, which will then force the method to return null (without looking at any other items)
You are missing a return statement right at the end, after the while loop.
This is needed to handle the case where the while loop guard becomes false, either by items being empty, or searching being set to false.
The compiler has no way of determining whether these will never become false, so you it requires you to return in case they do.
All functions that have a type (aren't void) require that you return something based on the method signature. This means that you must return something in ALL cases. You haven't included the case where searching is not true, and must return something if that is the case.
if(searching){
return null;
} else{
//return something else
}
It is important to note though that in this case the else is implicit, and therefore you don't actually have to provide the else. You could instead just do this:
if(searching){
return null;
}
//return something else
Keep in mind that if searching is true, it will return null and "return something else" will never be called.
Do like this
public InventoryItem findInventoryItem(int searchPartNumber)
{
int index = 0;
//boolean searching = true; comment out this line
InventoryItem inventoryItem = null; //declare null InventoryItem here
while (index < items.size())
{
inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if (fetchedPartNumber == (searchPartNumber))
{
//searching = false; comment out this line
break; //do something to get out from while loop
}
else {
inventoryItem = null;
index++;
}
}
return inventoryItem; //if found then it will have item otherwise null
}
First you need to return if items.size equals zero. Second you need to return if you find nothing. Third I can't see any usefulness of the variable searching.
You could change your searching function a bit. The final form would be something like this:
public InventoryItem findInventoryItem(int searchPartNumber) {
int index = 0;
while (index < items.size()){
InventoryItem inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if(fetchedPartNumber == searchPartNumber)
return inventoryItem;
else
index++;
}
return null;
}

Will Java notice when a loop won't change anything, or should I use break statement?

I would like to determine whether some element of String-List has some other String as a substring. My approach was something like
//...
boolean found = false;
for (String elem : myList) {
if (elem.contains(someString)) {
found = true;
break; // <-- necessary?
}
}
if (found) {
// do something
}
My Question is: is the break statement useful here? Intuitively it seems like omitting it would cause unnecessary work, since I am only interested in finding out whether the string is contained as a substring at least once.
However, a clever compiler could notice that after found has been set to true, the state of the program cannot change any more. Will the Java compiler or the JVM recognize this?
You're absolutely right. The break statement doesn't change the semantics of the algorithm (nor the complexity) but avoids doing unnecessary work once an element has been found.
(The JVM will most likely not discover that found never changes from true to false and break the loop in advance.)
I usually put this type of snippet in a method though, and use return statements as follows:
for (String elem : myList)
if (elem.contains(someString))
return true;
return false;
If you happen to be using Java 8, there's a better way though:
boolean found = myList.stream().anyMatch(s -> s.contains(someString));
Don't count on the compiler to break from the loop for you.
If you wish to avoid the break statement and still not do unnecessary work, you can re-write the loop this way :
boolean found = false;
for (int i = 0; i < myList.size() && !found; i++) {
if (myList.get(i).contains(someString)) {
found = true;
}
}
if (found) {
// do something
}
Or you can use a while loop.
I would use a while instead of a for loop:
//...
boolean found = false;
int i = 0;
while (i < myList.size() && !found) {
String elem = myList.get(i)
if (elem.contains(someString)) {
found = true;
}
i++;
}
if (found) {
// do something
}

Why return value of some methods such as: add(E), remove(Object), addAll,... is boolean in Collection FrameWork?

I'm a stupid student. I have a question that is the title.
I think when I do this, return boolean or not has no affect on me:
List<String> lst = new ArrayList<String>();
lst.add("whatever");
lst.remove("whatever");
And here is remove method(Which overrides from Collection< E > interface) of Arraylist Class in the API:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
I think if in Collection< E > interface, designers of the framework write public void remove(Object o); is ok but they have to have a certain purpose and I don't understand. Return boolean for what? Please tell me
In the case of remove:
It exactly tells you whether any object was removed from your collection or it wasn't.
In the case of add:
It's helpful in collections like Set, because it returns true if a new element added to the set, and it returns false, if the object is already in the collection.
From HashSet:
public boolean add(E e) {
return (this.map.put(e, PRESENT) == null);
}
At times, the client code might not know if the object to be removed is part of the collection. This client code would certainly like to know the effect of the remove operation. Hence, the design decision to return a boolean.
-- edit
For example,
Suppose, a synchronized collection is shared between two threads. One populates it and the other removes objects from it. The removing thread would like to know if the removal was successful.
remove(o) return false if o was not found in the collection.

Is there a way to shorten a conditional that contains a bunch of boolean comparisons?

e.g
if("viewCategoryTree".equals(actionDetail)
|| "fromCut".equals(actionDetail)
|| "fromPaste".equals(actionDetail)
|| ("viewVendorCategory".equals(actionDetail))&&"viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin())
|| ("viewVendorCategory".equals(actionDetail))&&"fromEdit".equals(vendorCategoryListForm.getActionOrigin())
|| "deleteSelectedItem".equals(actionDetail)
|| ("viewVendorCategory".equals(actionDetail))&&"fromLink".equals(vendorCategoryListForm.getActionOrigin())){
//do smth
}
I've tried something like this
if(check("deleteSelectedItem,viewCategoryTree,fromCut,fromPaste,{viewVendorCategory&&viewVendorCategory},{viewVendorCategory&&fromEdit},{viewVendorCategory&&fromLink}",actionDetail,actionOrigin)){
//do smth
}
public boolean check(String str, String ad, String ao){
String oneCmp = "";
String[] result = str.split(",");
ArrayList adList = new ArrayList();
ArrayList aoList = new ArrayList();
for (int i=0; i<result.length; i++){
oneCmp = result[i];
Matcher m = Pattern.compile("\\{([^}]*)\\}").matcher(oneCmp);
if(m.matches()){
m.find();
String agrp = m.group();
String[] groupresult = agrp.split("[\\W&&[^!]]+");
Boolean a = false;
Boolean b = false;
if(groupresult[0].startsWith("!")){
a = !groupresult[0].substring(1).equals(ad);
} else a = groupresult[0].equals(ad);
if(groupresult[1].startsWith("!")){
b = !groupresult[1].substring(1).equals(ao);
}else b = groupresult[1].equals(ao);
if(agrp.indexOf("&&")!=-1){
if(!(a && b))return false;
}
else if(agrp.indexOf("||")!=-1){
if(!(a || b))return false;
}
} else {
if(oneCmp.indexOf("^")==-1){
checklist(oneCmp,ad);
if(!checklist(oneCmp,ad))return false;
}else{
if(!checklist(oneCmp,ao))return false;
}
}
}
return false;
}
public boolean checklist(String str, String key){
if(str.startsWith("!")){
if(str.substring(1).equals(key))return false;
}else { if (!str.substring(1).equals(key)) return false;
}
}
return false;
}
is there a better way to do this ? thanks.
Move the check to a method that takes actionDetail as argument:
// Assumes vendorCategoryListForm is a member variable.
boolean check(String actionDetail) {
return ("viewCategoryTree".equals(actionDetail)
|| "fromCut".equals(actionDetail)
|| "fromPaste".equals(actionDetail)
|| (("viewVendorCategory".equals(actionDetail))
&&"viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin()))
|| (("viewVendorCategory".equals(actionDetail))
&&"fromEdit".equals(vendorCategoryListForm.getActionOrigin()))
|| "deleteSelectedItem".equals(actionDetail)
|| (("viewVendorCategory".equals(actionDetail))
&&"fromLink".equals(vendorCategoryListForm.getActionOrigin())))
}
if (check(actionDetail)) {
// do this
}
How about creating an array of what you need to test against.
And then some code like this:
arrayOfStrings = ["viewCategoryTree", ...]
match = false
for elem in arrayOfStrings:
if elem == actionDetail:
match = true
break
The good thing about an array is that it is easily extensible: you can easily add/remove elements to it both statically and dynamically.
Also kindly look at this post
Language Agnostic Credits to Galwegian
See Flattening Arrow Code for help.
1. Replace conditions with guard clauses.
2. Decompose conditional blocks into seperate functions.
3. Convert negative checks into positive checks.
Honestly, that code is no more readable. I would better suggest to encapsulate that conditional check into some property for the type like if (control.IsApplicable) { // do smth }.
No matter either you parameterize by one or two arguments.
But I suppose better solution is to have an array of matches that could be tested against and if matched then return true.
I don't think you are going to improve on this without adding a bunch of complexity, both in terms of the notation that you use to express the conditions and the implementation of the "engine" that evaluates them.
The notation issue is that: while you may end up expressing the conditions in fewer characters, someone else reading your code has to figure out what that funky string literal really means.
Besides, anything clever you do could have an impact on performance. For instance, your attempt compiles and applies a regex multiple times for each call to check.
Stick with what you've got would be my advice.
if(isValidActionDetail(actionDetail)
|| (isValidActionDetail(actionDetail)
&& ("viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin())
|| "fromEdit".equals(vendorCategoryListForm.getActionOrigin())
|| "fromLink".equals(vendorCategoryListForm.getActionOrigin())))){
//do smth
}
}
public static boolean isValidActionDetail (String actionDetail) {
return "viewCategoryTree".equals(actionDetail) || "fromCut".equals(actionDetail)
|| "fromPaste".equals(actionDetail) || "deleteSelectedItem".equals(actionDetail)
|| "viewVendorCategory".equals(actionDetail);
}
You can decompose in the above way, as the first step to refactoring your logic.

Categories

Resources