Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find sum in Java 8 based on a property of an object [duplicate]

I have a class defined like this:

public class Item {

    String name;
    double price;
}

Now I have a list of Item objects, now I want to find total price for all the items. How can we do this in Java 8?

If the list is of simple integers then we have solution given here - How to sum a list of integers with java streams?

like image 275
learner Avatar asked Oct 18 '18 20:10

learner


People also ask

How do you sum an object in Java?

Using Stream.collect() asList(1, 2, 3, 4, 5); Integer sum = integers. stream() . collect(Collectors. summingInt(Integer::intValue));

How to find duplicate characters in a string in java using stream?

Get the stream of elements in which the duplicates are to be found. For each element in the stream, count the frequency of each element, using Collections. frequency() method. Then for each element in the collection list, if the frequency of any element is more than one, then this element is a duplicate element.

How do you find the sum of a set of numbers in Java?

int sum = IntStream. of(arr). sum();


2 Answers

You can map the Items to their prices:

List<Item> items = ...;
double sum = items.stream().mapToDouble(Item::getPrice).sum();
like image 72
Mureinik Avatar answered Nov 14 '22 23:11

Mureinik


Why don't you use Double? It got methos sum() which might be a solution for you.

Example code:

class Entry {
    Double value;

    public Entry(Double value) {
        this.value = value;
    }
}

List<Entry> exampleList = new ArrayList<>();
for (int i = 0; i < 10; i++) { // Populate list
    exampleList.add(new Entry(10d));
}

Double sum = 0d;
for (Entry entry : exampleList) { //Sum up values
    Double.sum(sum, entry.value);
}

System.out.println(sum);

EDIT

Why you should not depend on wrapping primitives (Autoboxing) and declare Wrapper class directly

tldr;

STORING VALUES IN PRIMITIVES, AND USING COLLECTION IS LESS EFFICENT THEN DECLARING VARIABLE AS WRAPPER CLASS IN 1ST PLACE

As we can read in Java Documentation HERE, each time you use get() or set() on collection using primitive, the Autoboxing or Unboxing will occur, greatly lowering performance.

So when should you use autoboxing and unboxing? Use them only when there is an “impedance mismatch” between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.

Other pitfalls using Autoboxing

  • Cashing of Wrapper Class

As you can read in JavaDoc

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

According to this line, think what will be the output of

public class AutoboxingNotSoCool {
    public static void main(String[] args) {
        System.out.println(Integer.valueOf("-129") == (Integer.valueOf("-129")));
        System.out.println(Integer.valueOf("100") == (Integer.valueOf("100")));
    }
}

Result:

false
true

(Please not that you should NEVER compare two object's using ==)

  • You will need to manifestly declary number type

Let's look at this little piece of code.

public class AutoboxingNotSoCool {
    public static void main(String[] args) {
        Float manifestlyDeclaredVariable = 2F;

        System.out.println(manifestlyDeclaredVariable.equals(2));
        System.out.println(manifestlyDeclaredVariable.equals(2F));
    }
}

The result of this would be

false
true

And this is because 2 will be Autoboxed to Integer (2L will be Autoboxed to Long, 2F will be Autoboxed to Float)

like image 29
Wild_Owl Avatar answered Nov 14 '22 23:11

Wild_Owl