8

I need to create a null check in this formula for the books[i] and I am not entirely sure how to go about this as I am not greatly familiar with null checks and very new at programming. Any and all help is much appreciated!

public static double calculateInventoryTotal(Book[] books)
{
    double total = 0;

    for (int i = 0; i < books.length; i++)
    {
        total += books[i].getPrice();
    }

    return total;
}
CoShark
  • 129
  • 2
  • 2
  • 12

8 Answers8

12

First you should check if books itself isn't null, then simply check whether books[i] != null:

if(books==null) throw new IllegalArgumentException();

for (int i = 0; i < books.length; i++){
   if(books[i] != null){
        total += books[i].getPrice();
   }
}
Kuba Spatny
  • 26,618
  • 9
  • 40
  • 63
  • 1
    have you tried it with null as input value for books? – 1ac0 Feb 09 '14 at 21:45
  • @ladislavDANKO Thanks, I initially answer only what OP was asking for, but it is a good comment! Edited my answer. – Kuba Spatny Feb 09 '14 at 21:49
  • Old fashion programming, please update to Java 8, see my comment below. (And the worse is that the answer is incorrect, you don't use double for monetary calculations, that is the job of BigDecimal) – Marco Tulio Avila Cerón Apr 21 '18 at 07:48
4

You can add a guard condition to the method to ensure books is not null and then check for null when iterating the array:

public static double calculateInventoryTotal(Book[] books)
{
    if(books == null){
        throw new IllegalArgumentException("Books cannot be null");
    }

    double total = 0;

    for (int i = 0; i < books.length; i++)
    {
        if(books[i] != null){
            total += books[i].getPrice();
        }
    }

    return total;
}
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
3

If you are using Java 7 You can use Objects.requireNotNull(object[, optionalMessage]); - to check if the parameter is null. To check if each element is not null just use

if(null != books[i]){/*do stuff*/}

Example:

public static double calculateInventoryTotal(Book[] books){
    Objects.requireNotNull(books, "Books must not be null");

    double total = 0;

    for (int i = 0; i < books.length; i++){
        if(null != book[i]){
            total += books[i].getPrice();
        }
    }

    return total;
}
Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
  • Yoda tests have no value in java: Just code normally as `if (books == null)` – Bohemian Feb 09 '14 at 20:31
  • 1
    If you code only in java, they might not have any value, but if you program in more than one language, in which there is a difference, yoda checks are quite important and quickly become a habit. Even more I find them more readable :) – Svetlin Zarev Feb 09 '14 at 20:35
  • 1
    But this us a java question and nobody uses them in java. It's an industry standard thing. – Bohemian Feb 09 '14 at 20:42
  • 1
    ::raises hand:: I use them. Because of habit (one, quite frankly that I don't want to break because I'm a polyglot). And I'd be willing to bet I'm not the only one ;) – Brian Roach Feb 09 '14 at 20:53
2

If array of Books is null, return zero as it looks that method count total price of all Books provided - if no Book is provided, zero is correct value:

public static double calculateInventoryTotal(Book[] books)
{
if(books == null) return 0;
    double total = 0;
    for (int i = 0; i < books.length; i++)
    {
        total += books[i].getPrice();
    }
    return total;
}

It's upon to you to decide if it's correct that you can input null input value (shoul not be correct, but...).

1ac0
  • 2,875
  • 3
  • 33
  • 47
  • What is the correct result *is* `0`? In general, exceptions or `null` (via autoboxed return type) are preferred over using magic numbers. – Brian Roach Feb 09 '14 at 20:44
  • @BrianRoach It looks that `calculateInventoryTotal(Books[] books)` count total price of a provided Books. So if no Books is provided, total price is zero. So 0 is correct return value in this case, it's definitely no magic number. – 1ac0 Feb 09 '14 at 21:03
  • How do you differentiate between a `null` array being passed in, and an array containing one/all book with a price of `0`? The reason throwing an `IllegalArgumentException` is a better choice is because it prevents two different cases (one valid, one not) from producing the same result, and explicitly indicates a programming error. – Brian Roach Feb 09 '14 at 21:10
  • @BrianRoach do you need to diferentiate this? in hypothetical method `calculateInventoryCount(Book[] books)` you should need this but if you need total price - in real world price should be zero or higher than zero and doesn't matter if you don't have a book or you have hundreds of books. it depends on your analysis ;-) – 1ac0 Feb 09 '14 at 21:24
  • Note that I'm not downvoting your answer or anything, I just think that's it's important to explain to beginners the best-practice approach rather than something that works, right now, for what they're doing. Note the OP has actually accepted the least explanatory answer ::sigh:: – Brian Roach Feb 09 '14 at 21:28
  • @BrianRoach yes, i see :-) just thinking that in some situations there isn't need to over-exception-throwing, better should be look what method is doing. but of course, for beginer this should be confusing. – 1ac0 Feb 09 '14 at 21:42
2

You simply compare your object to null using the == (or !=) operator. E.g.:

public static double calculateInventoryTotal(Book[] books) {
    // First null check - the entire array
    if (books == null) {
        return 0;
    }

    double total = 0;

    for (int i = 0; i < books.length; i++) {
        // second null check - each individual element
        if (books[i] != null) {
            total += books[i].getPrice();
        }
    }

    return total;
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • What is the correct result *is* `0`? In general, exceptions or `null` (via autoboxed return type) are preferred over using magic numbers. – Brian Roach Feb 09 '14 at 20:46
  • this is only correct check for null values: at first check array and secondly check each element. – 1ac0 Feb 09 '14 at 21:58
1

Inside your for-loop, just add the following line:

if(books[i] != null) {
     total += books[i].getPrice();
}
John
  • 1,440
  • 1
  • 11
  • 18
  • Fair point; if the books parameter is null there'll be a NullPointerException, but I don't believe that is the type of null check that the questioner was talking about. – John Feb 09 '14 at 22:47
1

This question is quite older. The Questioner might have been turned into an experienced Java Developer by this time. Yet I want to add some opinion here which would help beginners.

For JDK 7 users, Here using

Objects.requireNotNull(object[, optionalMessage]);

is not safe. This function throws NullPointerException if it finds null object and which is a RunTimeException.

That will terminate the whole program!!. So better check null using == or !=.

Also, use List instead of Array. Although access speed is same, yet using Collections over Array has some advantages like if you ever decide to change the underlying implementation later on, you can do it flexibly. For example, if you need synchronized access, you can change the implementation to a Vector without rewriting all your code.

public static double calculateInventoryTotal(List<Book> books) {
    if (books == null || books.isEmpty()) {
        return 0;
    }

    double total = 0;

    for (Book book : books) {
        if (book != null) {
            total += book.getPrice();
        }
    }
    return total;
}

Also, I would like to upvote @1ac0 answer. We should understand and consider the purpose of the method too while writing. Calling method could have further logics to implement based on the called method's returned data.

Also if you are coding with JDK 8, It has introduced a new way to handle null check and protect the code from NullPointerException. It defined a new class called Optional. Have a look at this for detail

Finally, Pardon my bad English.

rookie4evr
  • 53
  • 6
0
public static double calculateInventoryTotal(Book[] arrayBooks) {

    final AtomicReference<BigDecimal> total = new AtomicReference<>(BigDecimal.ZERO);
    Optional.ofNullable(arrayBooks).map(Arrays::asList).ifPresent(books -> books.forEach(book -> total.accumulateAndGet(book.getPrice(), BigDecimal::add)));
    return total.get().doubleValue();

}