Sum and Average of Java Array List Elements - java

I have an exception in my Java program. When I run this code:
ArrayList<Integer> sum = new ArrayList<Integer>();
sum.add(10);
sum.add(15);
sum.add(20);
int total = 0;
int avg;
for(int i = 0; i < sum.size(); i++)
{
total += sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
}
It prints each ArrayList index element then prints the average, but when I run this code:
for(int i = 0; i<sum.size(); i++)
total = total+sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
It prints the average, but I have not given the bracket of the for loop.
How does the code compare?

Lambda stream method in Java 8 can solve this in a easy way:
int myArray[] = { 1, 2, 3 };
Arrays.stream(myArray).average();

The brackets are use to define block of statement
By default, a loop or a condition only read one statement. A statement could be one line or a block of statement
So here is a line
total=total+sum.get(i);
and here is the block of statement
{
total += sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
}
NOTE : You speak about exception but also said that there is an output in both cases, so I guess your exception is not a Java Exception but just some misunderstanding in this behavior.
EDIT : You should change avg type to accept decimal values and you are going to change a bit the line, the easier is to add a static value of float to convert the value :
float avg = 1.0f * total / sum.size();
Because there is a float here (1.0f), the result will be a float, if you only use integers, the result will be rounded in integer (even if you store it in a float).

From your question, I guess that you are learning Java.
If you are in Java 8, you might use Stream (see link for a better explanation):
The new Stream API allows to transform (map), filter values, etc.
It allows to collect them (see Collectors), regrouping them by key (groupingBy), and in your case to compute a summary statistics.
The example below shows you how to do that using either an IntStream (a Stream tailored for int) or a standard Stream:
IntSummaryStatistics stats = Arrays.asList(10, 15, 20)
.stream()
.mapToInt(Integer::intValue)
.summaryStatistics()
;
// alternative
// IntSummaryStatistics stats2 = Arrays.asList(10, 15, 20)
// .stream()
// .collect(Collectors.summarizingInt(Integer::intValue))
// ;
System.out.println("average: " + stats.getAverage());
System.out.println("count: " + stats.getCount());
System.out.println("sum: " + stats.getSum());
See the javadoc for Collectors.summarizingInt.

In java curly braces are used to group the line of code. In first block of code
ArrayList<Integer> sum = new ArrayList<Integer>();
sum.add(10);
sum.add(15);
sum.add(20);
int total = 0;
int avg;
for(int i = 0; i < sum.size(); i++)
{
total += sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
}
in this code you are adding element to total and same time you are calculating average. Let us see each iteration
iteration 1:
total = 10
avg = 10/3 = 3
iteration 2:
total = 25
avg = 25/3 = 8
iteration 3:
total = 45
avg = 45/3 = 15
But in case of second code block
for(int i = 0; i<sum.size(); i++)
total = total+sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
here code is equivalent to
for(int i = 0; i<sum.size(); i++){
total = total+sum.get(i);
}
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
so in for loop, it calculates total only as
iteration 1: total = 10
iteration 2: total = 15
iteration 2: total = 45
after completion of block value of total is 45
and after block, actual average is calculated as:
avg = 45/3 = 15
In java if we don't provide curly braces to group block of code inside for, if and while by default considered only single line inside the block and execute it repeatedly based on condition.

Exception is according to you Is not achieving the expected behaviour for an average on the elements of the collections.
So, as the earlier answer it boiles down to the Java syntax for working with the Loops/conditions/statements that how we use the { // code
}
By defaults a single line of code statement followed after Loops/conditions does not need to wrap in the braces {}
Here the first snippet uses a block of statement to derive average on each element by collecting it in total and dividing with size of collection.
Whereas, the second snippet does the collection of total for all element at first and then go for finding average.
You need to account for the data precisions when deriving mathematical values like avg and use the appropriate primitive data type.

If you remove the braces, the for loop header refers to the (one) very next statement, so the following two examples are equal:
for(int i=0; i<sum.size(); i++)
total=total+sum.get(i);
avg=total/sum.size();
System.out.println("The Average IS:" + avg);
for(int i=0; i<sum.size(); i++) {
total=total+sum.get(i);
}
avg=total/sum.size();
System.out.println("The Average IS:" + avg);

When you leave the brackets for the loop away, then just the first following line will be part of the loop. That means:
for(int i=0; i<sum.size(); i++)
total=total+sum.get(i);
avg=total/sum.size();
System.out.println("The Average IS:" + avg);
Is equivalent to
for(int i=0; i<sum.size(); i++){
total=total+sum.get(i);
}
avg=total/sum.size();
System.out.println("The Average IS:" + avg);
Same counts also for e.g. if/else.

1st
for(int i = 0; i < sum.size(); i++)
{
total += sum.get(i);
}
2nd
for(int i = 0; i < sum.size(); i++)
total += sum.get(i);
//but in this for loop it considers only one statement as inside for loop
3rd
for(int i = 0; i < sum.size(); i++)
total += sum.get(i);//only this statement is considered as inside the loop
System.out.println("hello");//this statements is not considered inside the loop
1st and 2nd for loops are same

You need to insert bracket in 2nd code of for loop the following.
for(int i = 0; i<sum.size(); i++) {
total = total+sum.get(i);
avg = total / sum.size();
System.out.println("The Average IS:" + avg);
}
Because if you don't insert bracket in for loop, only one line under the for loop will execute for looping process. So you need to make bracket for starting line to ending line that you want to execute in looping process.

Related

How would I calculate the standard deviation from a file of floating point numbers?

I'm trying to write a Java program to calculate the maximum, minimum, mean and standard deviation after reading a text file full of floating point numbers. As you can see, I've calculated the max, min, mean, but for the standard deviation, I'm confused. Any ideas how I should implement this?
Also, I'm fairly new to programming, so sorry if things aren't structured correctly.
Here's my code:
/*
* Create a Java program to read a file of floating point numbers and compute
* the following statistics from the data file:
*
* 1. Maximum
* 2. Minimum
* 3. Arithmetic Average (Mean)
* 4. Standard Deviation
*
* Do not assume anything about the large numbers in the file. They could be
* positive or negative, and their magnitude could be extremely large or
* extremely small.
*/
import java.io.*;
import java.util.Scanner;
public class DataFile {
public static void main(String[] args) {
// declare variables
double number, maximum, minimum, sum, mean, standardDeviation;
int count;
Scanner file = null;
/* -------------------------------------------------------------------------- */
try {
file = new Scanner(new File("RawData.txt"));
}
catch(FileNotFoundException e) {
System.out.print("Error; The program was terminated!");
System.exit(1);
}
/* -------------------------------------------------------------------------- */
// initialize variables
maximum = file.nextDouble();
minimum = maximum;
sum = 0;
count = 1;
while(file.hasNextDouble()) {
number = file.nextDouble();
if(number > maximum)
maximum = number;
else if(number < minimum)
minimum = number;
sum += number;
count += 1;
} // end while loop
file.close();
/* -------------------------------------------------------------------------- */
// mean calculation
mean = sum / count;
// standard deviation calculation
// .....
// display statistics
System.out.println("Maximum ------------> " + maximum );
System.out.println("Minimum ------------> " + minimum );
System.out.println("Sum ----------------> " + sum );
System.out.println("Count --------------> " + count );
System.out.println("Mean ---------------> " + mean );
} // end method main
} // end class DataFile
As suggested by Przemysław MoskalI, I believe something like this is what you are after! Lists are incredibly useful in Java. This was done very quickly, so make sure you are happy with the final calcs! Happy Programming!
Edited - used computational formula thanks to a suggestion from Bathsheba, which allows you to not make use of a list at all (which is more memory efficient).
See this website for an easy way to understand the calculation:
https://www.mathsisfun.com/data/standard-deviation-formulas.html
// initialize variables
maximum = file.nextDouble();
minimum = maximum;
sum = 0;
count = 1;
double computationalSum = 0;
double squareSum = 0;
while(file.hasNextDouble()) {
number = file.nextDouble();
squareSum += Math.pow(number, 2);
computationalSum += number;
if(number > maximum)
maximum = number;
else if(number < minimum)
minimum = number;
sum += number;
count += 1;
} // end while loop
file.close();
/* ------------------------------------------------------------------------*/
// mean calculation
mean = sum / count;
double stdDevSum = 0;
double stdDevMean = 0;
double stdDev = 0;
double sumOfSquares = squareSum - ((Math.pow(computationalSum, 2)/(count-1)));
double sSquared = sumOfSquares/(count-1);
double otherStdDev = Math.sqrt(sSquared);
// display statistics
System.out.println("Maximum ------------> " + maximum );
System.out.println("Minimum ------------> " + minimum );
System.out.println("Sum ----------------> " + sum );
System.out.println("Count --------------> " + count );
System.out.println("Mean ---------------> " + mean );
System.out.println("StdDev -------------> " + otherStdDev);
} // end method main
It the while loop you could put each of number into the ArrayList that is initialized before this loop. When you reach the end of a file you could change the values in your ArrayList - you need to provide a loop to store in thata list the difference between the values already in list and the mean and you square that difference. After you loop entire ArrayList, you sum the values from ArrayList, divide it with the count and then you just need the element of that result.

Percentage calculation staying at first element in for loop

EDIT: Added code to show frequency count
This is not homework. I'm doing this for fun.
I hope this small snippet of code will suffice, but I've run into a strange issue. I counted the frequency of each number in an array, and that works fine. Well, I wanted to see the percentage of those frequencies, so I created a little method to calculate it.
Since the first element's frequency was 42, and my total characters were 1,553, it printed 2.7% for every element, rather than changing for the different frequencies.
I set up breakpoints during debugging, and once the frequency counter calculates the first element's frequency, that value sticks with the rest of the elements. O.o
I tried placing a for loop outside the percentage calculation, and it did the exact same thing. It never broke away from that first frequency counter.
System.out.println(" FREQUENCY COUNT RESULT");
Collections.sort(array);
Hashtable<Integer, Integer> table = new Hashtable<>();
for (int i = 0; i < array.size(); i++) {
if (table.containsKey(array.get(i))) {
count = table.get(array.get(i));
table.put(array.get(i), ++count);
} else {
table.put(array.get(i), 1);
}
}
set = table.keySet();
count = 0;
for (Integer n : set) {
count = table.get(n);
System.out.println(n + ": Frequency - " + count);
}
System.out.println("TOTAL CHARACTERS IN ARRAY: " + countNonSpaces(array));
System.out.println();
System.out.println("PERCENTAGE REPORT");
for(Integer n : set) {
System.out.println(n + " Percentage: " + getPercentage(count, tally) + "%");
}
}
public static double getPercentage(int count, int tally) {
percentCounter = (count * 100.0) / tally;
percentCounter = percentCounter * 100;
percentCounter = Math.round(percentCounter);
percentCounter = percentCounter / 100;
return percentCounter;
}
public static int countNonSpaces(ArrayList<Integer> array) {
for (int i = 0; i < array.size(); i++) {
if (array.get(i) != ' ') {
tally++;
}
}
return tally;
}
Everything is working except the percentage counter, so that's why I left the other code out.
This is a portion of the frequency output:
10: Frequency - 54
9: Frequency - 33
8: Frequency - 37
7: Frequency - 42
6: Frequency - 35
5: Frequency - 36
4: Frequency - 40
3: Frequency - 50
2: Frequency - 39
1: Frequency - 42 //<---IT'S STUCK HERE...????
TOTAL CHARACTERS IN ARRAY: 1553
And this is the output of the same elements and their (incorrect) percentages:
10 Percentage: 2.7%
9 Percentage: 2.7%
8 Percentage: 2.7%
7 Percentage: 2.7%
6 Percentage: 2.7%
5 Percentage: 2.7%
4 Percentage: 2.7%
3 Percentage: 2.7%
2 Percentage: 2.7%
1 Percentage: 2.7%
You are looping through a set, but not using any value from this set.
for(Integer n : set) {
System.out.println(n + " Percentage: " + getPercentage(count) + "%");
}
It is hard to tell from your code, but if the set contains your Frequency and your count then you could calculate it
for(SomeObj n : set) {
System.out.println(" Percentage: " + getPercentage(n.tally, n.count) + "%");
}
Basically you need both the tally and the count to calculate the percentage. The tally and the count will be different for each row, and therefore need both to be stored in your set.
the count variable you pass to getPercentage in your printing loop doesnt get updated at any stage during the loop.
You need to add getting count to your for loop for printing percentage, just as it is for the for loop for printing frequency
for(Integer n : set) {
count = table.get(n); // add this line in the loop for printing percentage
System.out.println(n + " Percentage: " + getPercentage(count, tally) + "%");
}
EDIT Added code to show most frequent occurrences
Alright, I slept on it and tried again this morning. I set up breakpoints to see what was going on, and the counter was sticking at the first element, in which case was the integer 39, with a count of 42 occurrences. Every percentage was displaying as the percentage of 42 / 1558 (the tally of all characters excluding whitespaces).
Since the percentage was essentially the same as the count, just divided by the tally, I got rid of the percentage method altogether, looped through the elements again, and made sure to reset the counter before entering the second loop. Here is the changed code (only including the count and tally methods. The other method is getFileInfo(), which just gets the numbers from a text file and puts them in an array):
public static void getCount(ArrayList<Integer> array) {
Hashtable<Integer, Integer> table = new Hashtable<>();
for (int i = 0; i < array.size(); i++) {
if (table.containsKey(array.get(i))) {
count = table.get(array.get(i));
table.put(array.get(i), ++count);
} else {
table.put(array.get(i), 1);
}
}
set = table.keySet();
count = 0;
for (Integer n : set) {
count = table.get(n);
System.out.println(n + ": Frequency - " + count);
}
System.out.println();
count = 0;
System.out.println("PERCENTAGE REPORT");
for(Integer n : set) {
tally = 0; //<---Tally was being calculated twice. Had to reset.
countNonSpaces(array); //get the tally once more after resetting
count = table.get(n);
double percentage = (count*100.0)/tally; //percentage is essentially "count" with an additional calculation so no new method needed
percentage = percentage * 100;
percentage = Math.round(percentage);
percentage = percentage/100;
System.out.println(n + ": Percentage - " + percentage + "%");
}
System.out.println();
System.out.println("MOST SIGNIFICANT PERCENTAGES");
count = 0;
for(Integer n : set) {
tally = 0;
countNonSpaces(array);
count = table.get(n);
percentage = (count*100.0)/tally;
percentage = percentage * 100;
percentage = Math.round(percentage);
percentage = percentage/100;
// Picked a decent number (50), copied the code
// from the frequency calculation, and added
// a continue statement to only print the most frequent #'s.
if(count < 50) {
continue;
}
System.out.println(n + ": Percentage - " + percentage + "%");
}
}
public static int countNonSpaces(ArrayList<Integer> array) {
for (int i = 0; i < array.size(); i++) {
if (array.get(i) != ' ') {
tally++;
}
}
return tally;
}
}
For the sake of brevity, I won't show every integer, but this is the new (and correct) output:
FREQUENCY COUNT RESULT
10: Frequency - 54
9: Frequency - 33
8: Frequency - 37
7: Frequency - 43
6: Frequency - 36
5: Frequency - 37
4: Frequency - 41
3: Frequency - 50
2: Frequency - 39
1: Frequency - 42
PERCENTAGE REPORT
10: Percentage - 3.47%
9: Percentage - 2.12%
8: Percentage - 2.37%
7: Percentage - 2.76%
6: Percentage - 2.31%
5: Percentage - 2.37%
4: Percentage - 2.63%
3: Percentage - 3.21%
2: Percentage - 2.5%
1: Percentage - 2.7%
TOTAL CHARACTERS IN ARRAY: 1558
MOST SIGNIFICANT PERCENTAGES
29: Percentage - 3.21%
15: Percentage - 3.59%
11: Percentage - 3.27%
10: Percentage - 3.47%
3: Percentage - 3.21%
Thanks for helping get my gears turning. It's much appreciated. :-)

Totaling up from an array converted from a string to an integer(command line compiling)

I am compiling the code in command line with the following code typed in command line:
java aac 2 4 6 8 10
and I am getting the result:
5
The number in position 0 is 2.0
The Sum is: 2.0
The number in position 1 is 4.0
The Sum is: 4.0
The number in position 2 is 6.0
The Sum is: 6.0
The number in position 3 is 8.0
The Sum is: 8.0
The number in position 4 is 10.0
The Sum is: 10.0
What I am trying to achieve is, for the sum to be the total of all the numbers divided by the amount of numbers, however for the amount of numbers there is I have come up with a length variable. For this example the length is displayed as 5 right at the start.
public class aac {
public static void main(String args[]) {
// working out the length
int length = args.length;
System.out.println(length);
// this is a for loop that repeats until integer i is greater than
// integer length, which is the length of the args String array.
for (int i = 0; i < length; i++) {
// this string equals whatever value is in position i in string array args
String all = args[i];
// integer numConvert now equals the integer of String all
double numConvert = Double.parseDouble(all);
System.out.print("The number in position " + i + " is " + " ");
System.out.println(numConvert);
double sum = 0;
sum = sum += numConvert;
System.out.println("The Sum is: " + sum);
System.out.println();
}
}
}
Are you having problems creating the sum in order to calculate the average? If so, move the double sum = 0; out of your for loop. After the loop you divide it by args.length and that'll be your average.
Here's a little amelioration of your code :
double average = 0.0;
double sum = 0;
for(int i = 0; i < length; i++){
String all = args2[i];
double numConvert = Double.parseDouble(all);
System.out.print("The number in position "+i+" is ");
System.out.println(numConvert);
sum += numConvert;
average = sum / (i+1);
System.out.println("The Sum is: "+sum);
System.out.println("The average is :" + average);
System.out.println();
}
I created 2 double variables outside of your for loop.
Each time we loop in, the current value is added to the sum variable to get the total sum.
Also, the average is changed to the value of sum divided by the numbers we've already seen.
Here is the output :
5
The number in position 0 is 2.0
The Sum is: 2.0
The average is :2.0
The number in position 1 is 4.0
The Sum is: 6.0
The average is :3.0
The number in position 2 is 6.0
The Sum is: 12.0
The average is :4.0
The number in position 3 is 8.0
The Sum is: 20.0
The average is :5.0
The number in position 4 is 10.0
The Sum is: 30.0
The average is :6.0

How to Write a Summation of Fives in Java

I need to write a program in Java that can take the multiples of five up to a value given by the user, and then add all of the multiples together. I need to write it with a while loop.
Here's what I have so far:
import java.util.Scanner;
public class SummationOfFives {
public static void main(String[] args){
//variables
double limit;
int fives = 0;
//Scanner
System.out.println("Please input a positive integer as the end value: ");
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
limit = input.nextDouble();
//While Loop
while ((fives+5)<=limit)
{
fives = fives+5;
System.out.println("The summation is: "+fives);
}
}
}
When I run this program however, all it gives me is the multiples:
Please input a positive integer as the end value:
11
The summation is: 5
The summation is: 10
You're nearly there! Think about what your output is telling you. In your while loop, fives is the next multiple of 5 on each iteration. You're not adding it to a total variable anywhere.
So - define a total before the loop e.g.
int total = 0;
keep adding to it in the loop (where your System.out.println is now) e.g.
total = total + fives;
output the total after the loop e.g.
System.out.println(total);
I added a total variable into your loop that will accumulate the value of all of the summations.
int counter =1;
int total = 0;
//While Loop
while ((fives+5)<=limit)
{
total = counter*5;
counter++;
fives = fives+5;
System.out.println("The summation is: "+fives);
System.out.println("The total is: "+total);
}
The summation you do in fives is wrong. You need another variable multiple initialised to 0 that you will increment by 5 at each step of the loop. The stop condition in the while is (multiple < limit). Then fives are the sum of the multiples.
double limit;
int fives = 0;
int multiple = 0
//While Loop
while (multiple<=limit)
{
multiple += 5;
fives = fives + multiple;
System.out.println("So far, the summation is: "+fives);
}

java, timing three different loops

While reading essential java item45, there are three different simple loops as shown in the code below with timing. The first and the third is preferred. But when I time them,
for N < 1,000,000:
length of the list: 1000000
sum is: 499999500000
fast method time: 25
sum is: 499999500000
slower method time: 5
sum is: 499999500000
range method time: 21
the second method is actually faster, I think this may because java compiler is smart enough to substitute the a.size() with the actual number.
However, when N grows, the second method indeed becomes slower. I am aware this experiment is naive and machine specific. I wonder if there is an explanation for the second method outperform the other two when N is small. (the program have been run multiple times)
length of the list: 10000000
sum is: 49999995000000
fast method time: 44
sum is: 49999995000000
slower method time: 48
sum is: 49999995000000
range method time: 37
The code:
public static void main(String [] args){
// test the speed of initialize 1 million elements
// timing two different loops.
// int N = 10000000;
int N = 1000000;
List<Integer> a = new ArrayList<Integer>();
for(int i = 0; i < N; ++i){
a.add(i);
}
System.out.println("length of the list: " + a.size());
long t1 = System.currentTimeMillis();
long sum = 0;
for(int i = 0, n = a.size(); i < n; ++i){
sum += a.get(i);
}
long t2 = System.currentTimeMillis();
System.out.println("sum is: " + sum);
System.out.println("fast method time: " + (t2 - t1));
t1 = System.currentTimeMillis();
sum = 0;
for(int i = 0; i < a.size(); ++i){
sum += a.get(i);
}
t2 = System.currentTimeMillis();
System.out.println("sum is: " + sum);
System.out.println("slower method time: " + (t2 - t1));
t1 = System.currentTimeMillis();
sum = 0;
for(int i: a){
sum += i;
}
t2 = System.currentTimeMillis();
System.out.println("sum is: " + sum);
System.out.println("range method time: " + (t2 - t1));
}
I was indeed having the same results than you:
length of the list: 1000000
sum is: 499999500000
fast method time: 32
sum is: 499999500000
slower method time: 12
sum is: 499999500000
range method time: 24
So I used javap -c to dissasemble the bytecode, and I saw that javac was not making any kind of optimization when seeing that N was small, and in deed, no optimization was being done.
So, I tried exchanging the order of the first two statements, and here is the result:
length of the list: 1000000
sum is: 499999500000
slower method time: 30
sum is: 499999500000
fast method time: 8
sum is: 499999500000
range method time: 25
So the difference between those two methods is not the method itself, but which one happens first will be the slower.
As for why it happens, it is still puzzling me (maybe deferred loading of some class? hot-code native compilation?)

Categories

Resources