How to take average of Double[] in java - java

I have a map like following
Map<String, Double[]> userVecs;
userVecs.put("foo", [1.1, 2.2, 3.3]);
userVecs.put("bar", [0, 4, 2]);
I want an average vec which in this case is:
[1.1+0, 2.2+4, 3.3+2] / 2;
= [0.55, 3.1, 2.65]
I have an ugly two loop approach. I was wondering if there is a better way to do this.

Here is one way. It presumes the arrays are all the same length.
declare a sum array of the proper length.
iterate over the map values and add them via Arrays.setAll()
then find the average using userVecs.size() and Arrays.setAll()
Map<String, double[]> userVecs = new HashMap<>();;
userVecs.put("foo", new double[]{1.1, 2.2, 3.3});
userVecs.put("bar", new double[]{0, 4, 2});
double[] sums = new double[userVecs.get("foo").length];
for (double[] dar : userVecs.values()) {
Arrays.setAll(sums, i->sums[i]+dar[i]);
}
Arrays.setAll(sums, i->sums[i]/userVecs.size());
System.out.println(Arrays.toString(sums));
prints
[0.55, 3.1, 2.65]
The Arrays class has many useful features you may want to get familiar with.

Unless you want to use an external Math library, you're gonna wanna just write the extra function.
public static void main(String[] args) {
double[] arr1 = { 1.0, 2.0, 3.0 };
double[] arr2 = { 1.0, 1.0, 1.0 };
double[] avg = elementWiseAvg(arr1, arr2);
}
public static double[] elementWiseAvg(double[] arr1, double[] arr2) {
if (arr1.length != arr2.length) {
throw new IllegalArgumentException("Arrays must be the same length.");
}
double[] ret = new double[arr1.length];
for (int i = 0; i < arr1.length; ++i) {
ret[i] = (arr1[i] + arr2[i]) / 2;
}
return ret;
}

You have a two-loop approach, but that's not necessarily ugly. What you are effectively doing is summing two matrices of a single dimension. Like was pointed out in another answer unless you want to import a math library, you're going to have to roll your own.
If you would like to explore an external library, look to jblas, it's a linear algebra library for Java. Here's an example of summing and averaging those two vectors using jblas.
DoubleMatrix matrix1 = new DoubleMatrix(3, 1, 1.1, 2.2, 3.3);
DoubleMatrix matrix2 = new DoubleMatrix(3, 1, 0, 4, 2);
DoubleMatrix sum = matrix1.addColumnVector(matrix2).div(2);
log.info(sum);
The output is [0.550000; 3.100000; 2.650000]

Here is a solution with Java 8 Streams.
The approach is to create a stream over the values of the given map, i.e. a stream of arrays Double[]. Then inside a collector, created using Collector.of() sum up array values for every index and as a final step divide each the value at each index by the map size.
In order to preserve arrays in the source map intact, we need to find out the length of these array and collect the data into a newly created array.
public static Double[] getAverage(Map<String, Double[]> userVecs) {
if (userVecs.isEmpty()) {
return new Double[0]; // throw an exception depending on your needs
}
int size = userVecs.values().iterator().next().length; // the map is proved to be non-empty, we can safely access one of its elements to find out the size of the resulting array
return userVecs.values().stream()
.collect(Collector.of(
() -> Stream.generate(() -> 0d).limit(size).toArray(Double[]::new), // mutable container
(Double[] res, Double[] next) -> mergeArrays(res, next), // accumulator - populating the container
(left, right) -> mergeArrays(left, right), // combiner - merging containers while executing in parallel
res -> toAverage(res, userVecs.size()) // finisher - transforming the container into a final result
));
}
public static Double[] mergeArrays(Double[] res, Double[] next) {
for (int i = 0; i < res.length; i++) res[i] += next[i];
return res;
}
public static Double[] toAverage(Double[] res, int mapSize) {
for (int i = 0; i < res.length; i++) res[i] /= mapSize;
return res;
}
main()
public static void main(String[] args) {
Map<String, Double[]> userVecs = new HashMap<>();
userVecs.put("foo", new Double[]{1.1, 2.2, 3.3});
userVecs.put("bar", new Double[]{0d, 4d, 2d});
System.out.println(Arrays.toString(getAverage(userVecs)));
}
Output:
[0.55, 3.1, 2.65]

Related

I am trying to get the mode of an input of ten numbers in java

import java.util.*;
public class main {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] quiz = new int[10];
int mean = 0,mode = 0,median,range;
Scanner scan = new Scanner(System.in);
for(int x=0;x<=9;x++){
System.out.print("Enter quiz["+(x+1)+"]:");
quiz[x]= scan.nextInt();
}
Arrays.sort(quiz);
for(int x=0;x<=9;x++){
mean = mean+quiz[x];
}
mean = mean/10;
median = (quiz[4]+quiz[5])/2;
range = quiz[9]-quiz[0];
int[] cntr = new int[10];
for(int x=0;x<=9;x++){
for(int y=0;y<=9;y++){
if (quiz[x]==quiz[y]&&x!=y){
cntr[x]++;
}
}
}
int[] sortcntr = cntr;
int ndx = 0;
Arrays.sort(sortcntr);
for(int z=0;z<=9;z++){
if(cntr[z]==sortcntr[9]){
ndx = z;
}
else
mode=0;
}
mode = quiz[ndx];
System.out.println("Mean: "+mean);
System.out.println("Median: "+median);
System.out.println("Range: "+range);
if(mode==0){
System.out.println("Mode: none");
}
else
System.out.println("Mode: "+mode);
System.out.print(sortcntr[9]);
System.out.print(cntr[9]);
System.out.println(ndx);
}
}
this is the codes that i used everything is right except for the mode. the mode variable there always returns the highest number from the number. the latter part was just for debugging and not for use. please help
The main problem of your code is that you obviously think that the line
int[] sortcntr = cntr;
creates a copy of the array cntr. However, arrays have reference semantics in Java. Thus, you simply create a second reference to the same array. If you then sort sortcntr, it applies to cntr as well since it's the same array.
To create a copy of the array:
int[] sortcntr = new int[ cntr.length ];
System.arraycopy(cntr, 0, sortcntr, 0, cntr.length);
BTW: Wouldn't it make more sense to work with floating-point numbers (double) instead of integer numbers?
for(int x=0;x<=9;x++){
for(int y=0;y<=9;y++){
The inner loop should start at x+1, otherwise you count everything twice.
Just to help you out, if you decide to more generify (As Raffaele said) the process of getting the mode of a given set of data, here is a method I developed a while ago which will even return multiple modes if there are more than one with the same occurrence. (Uses the Java 8 Stream API)
/**
* Computes the mode of the passed integers.
*
* #param args Numbers to find the mode of.
* #return Mode of the passed numbers.
*/
public static int[] mode(int... args) {
/* Create a map of integers to their frequencies */
Map<Integer, Integer> frequencies = IntStream.of(args).collect(
HashMap::new,//Indicated that this collector will result in a HashMap
(integerIntegerMap, value) -> integerIntegerMap.merge(value, 1, Maths::sum), //For each value in the arguments added, merge it with the current map and add the frequencies
(integerIntegerMap, integerIntegerMap2) -> integerIntegerMap.putAll(integerIntegerMap2) //While this is not used, it simply combines 2 HashMaps. (I think this is only used when in parallel)
);
//Here we get the maximum number of occurrences for any number, we could return the mode here; but there could be multiple modes
int maxOccurrences = frequencies.entrySet().stream().mapToInt(Map.Entry::getValue).max().getAsInt();
//Here we simply go through the entry set again, filtering out only the numbers with a frequency equal to the max, then returning them as an array
return frequencies.entrySet().stream().filter(entry -> entry.getValue() == maxOccurrences).mapToInt(Map.Entry::getKey).toArray();
}
-Thomas
Since the input is already sorted to compute range and median, you can use the following code to get the mode after a single loop and without any extra memory (live on ideone):
// this must be sorted
int[] values = {1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8};
int mode = values[0];
int modeOccurrences = 1;
int occurrences = 1;
int current = values[0];
for (int i = 1; i < values.length; i++) {
int value = values[i];
if (value == current) {
occurrences++;
} else {
if (occurrences > modeOccurrences) {
mode = current;
modeOccurrences = occurrences;
}
occurrences = 1;
current = value;
}
}
if (occurrences > modeOccurrences) {
mode = current;
modeOccurrences = occurrences;
}
You can even generify this piece of code to work with plain objects instead of numerical types, provided modes can be sorted and compared (I used enums in my demo)

Find common elements in two unsorted array

I try to find a solution to this problem:
I have two arrays A and B of integers (A and B can have different dimensions). I have to find the common elements in these two arrays. I have another condition: the maximum distance between the common elements is k.
So, this is my solution. I think is correct:
for (int i = 0; i<A.length; i++){
for (int j=jlimit; (j<B.length) && (j <= ks); j++){
if(A[i]==B[j]){
System.out.println(B[j]);
jlimit = j;
ks = j+k;
}//end if
}
}
Is there a way to make a better solution? Any suggestions? Thanks in advance!
Given your explanation, I think the most direct approach is reading array A, putting all elements in a Set (setA), do the same with B (setB), and use the retainAll method to find the intersection of both sets (items that belong to both of the sets).
You will see that the k distance is not used at all, but I see no way to use that condition that leads to code either faster or more maintenable. The solution I advocate works without enforcing that condition, so it works also when the condition is true (that is called "weakening the preconditions")
IMPLEMENT BINARY SEARCH AND QUICK SORT!
this will lead to tons of code.... but the fastest result.
You can sort the elements of the larger array with like quick sort which would lead to O(nlogn).
then iterate through the smaller array for each value and do a binary search of that particular element in the other array. Add some logic for the distance in the binary search.
I think you can get the complexity down to O(nlogn). Worst case O(n^2)
pseudo code.
larger array equals a
other array equals b
sort a
iterate through b
binary search b at iterated index
// I would throw (last index - index) logic in binary search
// to exit out of that even faster by returning "NOT FOUND" as soon as that is hit.
if found && (last index - index) is less than or equal
store last index
print value
this is the fastest way possible to do your problem i believe.
Although this would be a cheat, since it uses HashSets, it is pretty nice for a Java implementation of this algorithm. If you need the pseudocode for the algorithm, don't read any further.
Source and author in the JavaDoc. Cheers.
/**
* #author Crunchify.com
*/
public class CrunchifyIntersection {
public static void main(String[] args) {
Integer[ ] arrayOne = { 1, 4, 5, 2, 7, 3, 9 };
Integer[ ] arrayTwo = { 5, 2, 4, 9, 5 };
Integer[ ] common = iCrunchIntersection.findCommon( arrayOne, arrayTwo );
System.out.print( "Common Elements Between Two Arrays: " );
for( Integer entry : common ) {
System.out.print( entry + " " );
}
}
public static Integer[ ] findCommon( Integer[ ] arrayOne, Integer[ ] arrayTwo ) {
Integer[ ] arrayToHash;
Integer[ ] arrayToSearch;
if( arrayOne.length < arrayTwo.length ) {
arrayToHash = arrayOne;
arrayToSearch = arrayTwo;
} else {
arrayToHash = arrayTwo;
arrayToSearch = arrayOne;
}
HashSet<Integer> intersection = new HashSet<Integer>( );
HashSet<Integer> hashedArray = new HashSet<Integer>( );
for( Integer entry : arrayToHash ) {
hashedArray.add( entry );
}
for( Integer entry : arrayToSearch ) {
if( hashedArray.contains( entry ) ) {
intersection.add( entry );
}
}
return intersection.toArray( new Integer[ 0 ] );
}
}
Your implementation is roughly O(A.length*2k).
That seems to be about the best you're going to do if you want to maintain your "no more than k away" logic, as that rules out sorting and the use of sets. I would alter a little to make your code more understandable.
First, I would ensure that you iterate over the smaller of the two arrays. This would make the complexity O(min(A.length, B.length)*2k).
To understand the purpose of this, consider the case where A has 1 element and B has 100. In this case, we are only going to perform one iteration in the outer loop, and k iterations in the inner loop.
Now consider when A has 100 elements, and B has 1. In this case, we will perform 100 iterations on the outer loop, and 1 iteration each on the inner loop.
If k is less than the length of your long array, iterating over the shorter array in the outer loop will be more efficient.
Then, I would change how you're calculating the k distance stuff just for readability's sake. The code I've written demonstrates this.
Here's what I would do:
//not sure what type of array we're dealing with here, so I'll assume int.
int[] toIterate;
int[] toSearch;
if (A.length > B.length)
{
toIterate = B;
toSearch = A;
}
else
{
toIterate = A;
toSearch = B;
}
for (int i = 0; i < toIterate.length; i++)
{
// set j to k away in the negative direction
int j = i - k;
if (j < 0)
j = 0;
// only iterate until j is k past i
for (; (j < toSearch.length) && (j <= i + k); j++)
{
if(toIterate[i] == toSearch[j])
{
System.out.println(toSearch[j]);
}
}
}
Your use of jlimit and ks may work, but handling your k distance like this is more understandable for your average programmer (and it's marginally more efficient).
O(N) solution (BloomFilters):
Here is a solution using bloom filters (implementation is from the Guava library)
public static <T> T findCommon_BloomFilterImpl(T[] A, T[] B, Funnel<T> funnel) {
BloomFilter<T> filter = BloomFilter.create(funnel, A.length + B.length);
for (T t : A) {
filter.put(t);
}
for (T t : B) {
if (filter.mightContain(t)) {
return t;
}
}
return null;
}
use it like this:
Integer j = Masking.findCommon_BloomFilterImpl(new Integer[]{12, 2, 3, 4, 5222, 622, 71, 81, 91, 10}, new Integer[]{11, 100, 15, 18, 79, 10}, Funnels.integerFunnel());
Assert.assertNotNull(j);
Assert.assertEquals(10, j.intValue());
Runs in O(N) since calculating hash for Integer is pretty straight forward. So still O(N) if you can reduce the calculation of hash of your elementents to O(1) or a small O(K) where K is the size of each element.
O(N.LogN) solution (sorting and iterating):
Sorting and the iterating through the array will lead you to a O(N*log(N)) solution:
public static <T extends Comparable<T>> T findCommon(T[] A, T[] B, Class<T> clazz) {
T[] array = concatArrays(A, B, clazz);
Arrays.sort(array);
for (int i = 1; i < array.length; i++) {
if (array[i - 1].equals(array[i])) { //put your own equality check here
return array[i];
}
}
return null;
}
concatArrays(~) is in O(N) of course. Arrays.sort(~) is a bi-pivot implementation of QuickSort with complexity in O(N.logN), and iterating through the array again is O(N).
So we have O((N+2).logN) ~> O(N.logN).
As a general case solution (withouth the "within k" condition of your problem) is better than yours. It should be considered for k "close to" N in your precise case.
Simple solution if arrays are already sorted
public static void get_common_courses(Integer[] courses1, Integer[] courses2) {
// Sort both arrays if input is not sorted
//Arrays.sort(courses1);
//Arrays.sort(courses2);
int i=0, j=0;
while(i<courses1.length && j<courses2.length) {
if(courses1[i] > courses2[j]) {
j++;
} else if(courses1[i] < courses2[j]){
i++;
} else {
System.out.println(courses1[i]);
i++;j++;
}
}
}
Apache commons collections API has done this in efficient way without sorting
public static Collection intersection(final Collection a, final Collection b) {
ArrayList list = new ArrayList();
Map mapa = getCardinalityMap(a);
Map mapb = getCardinalityMap(b);
Set elts = new HashSet(a);
elts.addAll(b);
Iterator it = elts.iterator();
while(it.hasNext()) {
Object obj = it.next();
for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) {
list.add(obj);
}
}
return list;
}
Solution using Java 8
static <T> Collection<T> intersection(Collection<T> c1, Collection<T> c2) {
if (c1.size() < c2.size())
return intersection(c2, c1);
Set<T> c2set = new HashSet<>(c2);
return c1.stream().filter(c2set::contains).distinct().collect(Collectors.toSet());
}
Use Arrays::asList and boxed values of primitives:
Integer[] a =...
Collection<Integer> res = intersection(Arrays.asList(a),Arrays.asList(b));
Generic solution
public static void main(String[] args) {
String[] a = { "a", "b" };
String[] b = { "c", "b" };
String[] intersection = intersection(a, b, a[0].getClass());
System.out.println(Arrays.toString(intersection));
Integer[] aa = { 1, 3, 4, 2 };
Integer[] bb = { 1, 19, 4, 5 };
Integer[] intersectionaabb = intersection(aa, bb, aa[0].getClass());
System.out.println(Arrays.toString(intersectionaabb));
}
#SuppressWarnings("unchecked")
private static <T> T[] intersection(T[] a, T[] b, Class<? extends T> c) {
HashSet<T> s = new HashSet<>(Arrays.asList(a));
s.retainAll(Arrays.asList(b));
return s.toArray((T[]) Array.newInstance(c, s.size()));
}
Output
[b]
[1, 4]

add an element to int [] array in java [duplicate]

This question already has answers here:
How to add new elements to an array?
(19 answers)
Closed 6 years ago.
Want to add or append elements to existing array
int[] series = {4,2};
now i want to update the series dynamically with new values i send..
like if i send 3 update series as int[] series = {4,2,3};
again if i send 4 update series as int[] series = {4,2,3,4};
again if i send 1 update series as int[] series = {4,2,3,4,1}; so on
How to do it????
I generate an integer every 5 minutes in some other function and want to send to update the int[] series array..
The length of an array is immutable in java. This means you can't change the size of an array once you have created it. If you initialised it with 2 elements, its length is 2. You can however use a different collection.
List<Integer> myList = new ArrayList<Integer>();
myList.add(5);
myList.add(7);
And with a wrapper method
public void addMember(Integer x) {
myList.add(x);
};
try this
public static void main(String[] args) {
int[] series = {4,2};
series = addElement(series, 3);
series = addElement(series, 1);
}
static int[] addElement(int[] a, int e) {
a = Arrays.copyOf(a, a.length + 1);
a[a.length - 1] = e;
return a;
}
If you are generating an integer every 5 minutes, better to use collection. You can always get array out of it, if required in your code.
Else define the array big enough to handle all your values at runtime (not preferred though.)
You'll need to create a new array if you want to add an index.
Try this:
public static void main(String[] args) {
int[] series = new int[0];
int x = 5;
series = addInt(series, x);
//print out the array with commas as delimiters
System.out.print("New series: ");
for (int i = 0; i < series.length; i++){
if (i == series.length - 1){
System.out.println(series[i]);
}
else{
System.out.print(series[i] + ", ");
}
}
}
// here, create a method
public static int[] addInt(int [] series, int newInt){
//create a new array with extra index
int[] newSeries = new int[series.length + 1];
//copy the integers from series to newSeries
for (int i = 0; i < series.length; i++){
newSeries[i] = series[i];
}
//add the new integer to the last index
newSeries[newSeries.length - 1] = newInt;
return newSeries;
}
Like others suggested you are better off using collection. If you however for some reason must stick to array then Apache Commons ArrayUtils may help:
int[] series = {4,2};
series = ArrayUtils.add(series, 3); // series is now {4,2,3}
series = ArrayUtils.add(series, 4); // series is now {4,2,3,4};
Note that the add method creates a new array, copies the given array and appends the new element at the end, which may have impact on performance.
You could also try this.
public static int[] addOneIntToArray(int[] initialArray , int newValue) {
int[] newArray = new int[initialArray.length + 1];
for (int index = 0; index < initialArray.length; index++) {
newArray[index] = initialArray[index];
}
newArray[newArray.length - 1] = newValue;
return newArray;
}
The size of an array can't be changed. If you want a bigger array you have to create a new array.
However, a better solution would be to use an (Array)List which can grow as you need it. The method ArrayList.toArray(T[] a) returns an array if you need to use an array in your application.
public int[] return_Array() {
int[] a =new int[10];
int b = 25;
for(int i=0; i<10; i++) {
a[i] = b * i;
}
return a;
}
import java.util.Arrays;
public class NumberArray {
public static void main(String []args){
int[] series = {4,2};
int[] newSeries = putNumberInSeries(1,series);
System.out.println(series==newSeries);//return false. you won't get the same int[] object. But functionality achieved.
}
private static int[] putNumberInSeries(int i, int[] series) {
int[] localSeries = Arrays.copyOf(series, series.length+1);
localSeries[series.length] = i;
System.out.println(localSeries);
return localSeries;
}
}
The ... can only be used in JDK 1.5 or later. If you are using JDK 4 or lower, use this code:'
public static int[] addElement(int[] original, int newelement) {
int[] nEw = new int[original.length + 1];
System.arraycopy(original, 0, nEw, 0, original.length);
nEw[original.length] = newelement;
}
otherwise (JDK 5 or higher):
public static int[] addElement(int[] original, int... elements) { // This can add multiple elements at once; addElement(int[], int) will still work though.
int[] nEw = new int[original.length + elements.length];
System.arraycopy(original, 0, nEw, 0, original.length);
System.arraycopy(elements, 0, nEw, original.length, elements.length);
return nEw;
}
Of course, as many have mentioned above, you could use a Collection or an ArrayList, which allows you to use the .add() method.
class AddElement {
public static void main(String s[]) {
int arr[] ={2,3};
int add[] = new int[arr.length+1];
for(int i=0;i<add.length;i++){
if(i==add.length-1){
add[i]=4;
}else{
add[i]=arr[i];
}
System.out.println(add[i]);
}
}
}
This works for me:
int[] list = new int[maximum];
for (int i = 0; i < maximum; i++{
list[i] = put_input_here;
}
This way, it's simple, yet efficient.
similar to Evgeniy:
int[] series = {4,2};
add_element(3);
add_element(4);
add_element(1);
public void add_element(int element){
series = Arrays.copyOf(series, series.length +1);
series[series.length - 1] = element;
}
int[] oldArray = {1,2,3,4,5};
//new value
int newValue = 10;
//define the new array
int[] newArray = new int[oldArray.length + 1];
//copy values into new array
for(int i=0;i < oldArray.length;i++)
newArray[i] = oldArray[i];
//another solution is to use
//System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
//add new value to the new array
newArray[newArray.length-1] = newValue;
//copy the address to the old reference
//the old array values will be deleted by the Garbage Collector
oldArray = newArray;

Is there possibility of sum of ArrayList without looping

Is there possibility of sum of ArrayList without looping?
PHP provides sum(array) which will give the sum of array.
The PHP code is like
$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";
I wanted to do the same in Java:
List tt = new ArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
Once java-8 is out (March 2014) you'll be able to use streams:
If you have a List<Integer>
int sum = list.stream().mapToInt(Integer::intValue).sum();
If it's an int[]
int sum = IntStream.of(a).sum();
Then write it yourself:
public int sum(List<Integer> list) {
int sum = 0;
for (int i : list)
sum = sum + i;
return sum;
}
The only alternative to using a loop is to use recursion.
You can define a method like
public static int sum(List<Integer> ints) {
return ints.isEmpty() ? 0 : ints.get(0) + ints.subList(1, ints.length());
}
This is very inefficient compared to using a plain loop and can blow up if you have many elements in the list.
An alternative which avoid a stack overflow is to use.
public static int sum(List<Integer> ints) {
int len = ints.size();
if (len == 0) return 0;
if (len == 1) return ints.get(0);
return sum(ints.subList(0, len/2)) + sum(ints.subList(len/2, len));
}
This is just as inefficient, but will avoid a stack overflow.
The shortest way to write the same thing is
int sum = 0, a[] = {2, 4, 6, 8};
for(int i: a) {
sum += i;
}
System.out.println("sum(a) = " + sum);
prints
sum(a) = 20
Write a util function like
public class ListUtil{
public static int sum(List<Integer> list){
if(list==null || list.size()<1)
return 0;
int sum = 0;
for(Integer i: list)
sum = sum+i;
return sum;
}
}
Then use like
int sum = ListUtil.sum(yourArrayList)
for me the clearest way is this:
doubleList.stream().reduce((a,b)->a+b).get();
or
doubleList.parallelStream().reduce((a,b)->a+b).get();
It also use internal loops, but it is not possible without loops.
You can use apache commons-collections API.
class AggregateClosure implements org.apache.commons.collections.Closure {
int total = 0;
#Override
public void execute(Object input) {
if (input != null) {
total += (Integer) input;
}
}
public int getTotal() {
return total;
}
}
Then use this closure as shown below:
public int aggregate(List<Integer> aList) {
AggregateClosure closure = new AggregateClosure();
org.apache.commons.collections.CollectionUtils.forAllDo(aList, closure);
return closure.getTotal();
}
This can be done with reduce using method references reduce(Integer::sum):
Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
.stream()
.reduce(Integer::sum)
.get();
Or without Optional:
Integer reduceSum = Arrays.asList(1, 3, 4, 6, 4)
.stream()
.reduce(0, Integer::sum);
If you know about the map function, then you know that a map is also can be recursive loop or recursive loop. But obviously you have to reach each element for that. so, I could not work out the Java 8, because some syntax mismatch but wanted a very short so this is what I got.
int sum = 0
for (Integer e : myList) sum += e;
Given that a list can hold any type of object, there is no built in method which allows you to sum all the elements. You could do something like this:
int sum = 0;
for( Integer i : ( ArrayList<Integer> )tt ) {
sum += i;
}
Alternatively you could create your own container type which inherits from ArrayList but also implements a method called sum() which implements the code above.
ArrayList is a Collection of elements (in the form of list), primitive are stored as wrapper class object but at the same time i can store objects of String class as well. SUM will not make sense in that. BTW why are so afraid to use for loop (enhanced or through iterator) anyways?
Or switch to Groovy, it has a sum() function on a collection.
[1,2,3,4,5,6].sum()
http://groovy.codehaus.org/JN1015-Collections
Runs on the same JVM as your java classes.
This link shows three different ways how to sum in java, there is one option that is not in previous answers using Apache Commons Math..
Example:
public static void main(String args []){
List<Double> NUMBERS_FOR_SUM = new ArrayList<Double>(){
{
add(5D);
add(3.2D);
add(7D);
}
};
double[] arrayToSume = ArrayUtils.toPrimitive(NUMBERS_FOR_SUM
.toArray(new Double[NUMBERS_FOR_SUM.size()]));
System.out.println(StatUtils.sum(arrayToSume));
}
See StatUtils api
You can use GNU Trove library:
TIntList tt = new TIntArrayList();
tt.add(1);
tt.add(2);
tt.add(3);
int sum = tt.sum();

missing elements from two arrays in java

How can we find out missing elements from two arrays ?
Ex:
int []array1 ={1,2,3,4,5};
int []array2 ={3,1,2};
From the above two arrays i want to find what are the missing elements in second array?
Convert them to Sets and use removeAll.
The first problem is how to convert a primitive int[] to a collection.
With Guava you can use:
List<Integer> list1 = Ints.asList(array1);
List<Integer> list2 = Ints.asList(array2);
Apache commons (which I'm not familiar with) apparently has something similar.
Now convert to a set:
Set<Integer> set1 = new HashSet<Integer>(list1);
And compute the difference:
set1.removeAll(list2);
And convert the result back to an array:
return Ints.toArray(set1);
If you are allowed duplicates in the arrays, an efficient (O(n)) solution it to create a frequency table (Map) by iterating over the first array, and then use the map to match off any elements in the second array.
Map<Integer, Integer> freqMap = new HashMap<Integer, Integer>();
// Iterate over array1 and populate frequency map whereby
// the key is the integer and the value is the number of
// occurences.
for (int val1 : array1) {
Integer freq = freqMap.get(val1);
if (freq == null) {
freqMap.put(val1, 1);
} else {
freqMap.put(val1, freq + 1);
}
}
// Now read the second array, reducing the frequency for any value
// encountered that is also in array1.
for (int val2 : array2) {
Integer freq = freqMap.get(val2);
if (freq == null) {
freqMap.remove(val2);
} else {
if (freq == 0) {
freqMap.remove(val2);
} else {
freqMap.put(freq - 1);
}
}
}
// Finally, iterate over map and build results.
List<Integer> result = new LinkedList<Integer>();
for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
int remaining = entry.getValue();
for (int i=0; i<remaining; ++i) {
result.add(entry.getKey());
}
}
// TODO: Convert to int[] using the util. method of your choosing.
Simple logic for getting the unmatched numbers.
public static int getelements(int[] array1, int[] array2)
{
int count = 0;
ArrayList unMatched = new ArrayList();
int flag = 0;
for(int i=0; i<array1.length ; i++)
{ flag=0;
for(int j=0; j<array2.length ; j++)
{
if(array1[i] == array2[j]) {
flag =1;
break;
}
}
if(flag==0)
{
unMatched.add(array1[i]);
}
}
System.out.println(unMatched);
return unMatched.size();
}
public static void main(String[] args) {
// write your code here5
int array1[] = {7,3,7,2,8,3,2,5};
int array2[] = {7,4,9,5,5,10,4};
int count;
count = getelements(array1,array2);
System.out.println(count);
}
You can use Set and its methods. This operation would be a set difference.
The naive way would be to simply search one array for each of the elements of the other array (with a for loop). If you first were to SORT both arrays, it becomes much more efficient.
Consider using intersection method:
A healthy discussion is available at:
http://www.coderanch.com/t/35439/Programming-Diversions/Intersection-two-arrays
You could create two other int arrays to store the multiplicity of each value. Increment the index of the array that the value corresponds with every time it is found and then compare the arrays.
It's not the most "efficient" way perhaps, but it's a very simple concept that works.
Guava library can be helpful; you need to change Array in Set then can use API.
#finnw I believe you were thinking of commons-collections.
Need to import org.apache.commons.collections.CollectionUtils;
To get the disjunction function.
Using the disjunction method will find all objects that aren't found in an intersection.
Integer[] array1 ={1,2,3,4,5};
Integer[] array2 ={3,1,2};
List list1 = Arrays.asList(array1);
List list2 = Arrays.asList(array2);
Collection result = CollectionUtils.disjunction(list1, list2);
System.out.println(result); // displays [4, 5]
This is not the most efficient way but it's probably the simplest way that works in Java :
public static void main(final String[] args) {
final int[] a = { 1, 2, 3, 4, 5 };
final int[] b = { 3, 1, 2 };
// we have to do this just in case if there might some values that are missing in a and b
// example: a = { 1, 2, 3, 4, 5 }; b={ 2, 3, 1, 0, 5 }; missing value=4 and 0
findMissingValue(b, a);
findMissingValue(a, b);
}
private static void findMissingValue(final int[] x, final int[] y) {
// loop through the bigger array
for (final int n : x) {
// for each value in the a array call another loop method to see if it's in there
if (!findValueSmallerArray(n, y)) {
System.out.println("missing value: " + n);
// break;
}
}
}
private static boolean findValueSmallerArray(final int n, final int[] y) {
for (final int i : y) {
if (n == i) {
return true;
}
}
return false;
}

Categories

Resources