Is there possibility of sum of ArrayList without looping - java

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();

Related

What is the best way to check if ALL values in a range exist in an array? (java)

I have the task of determining whether each value from 1, 2, 3... n is in an unordered int array. I'm not sure if this is the most efficient way to go about this, but I created an int[] called range that just has all the numbers from 1-n in order at range[i] (range[0]=1, range[1]=2, ect). Then I tried to use the containsAll method to check if my array of given numbers contains all of the numbers in the range array. However, when I test this it returns false. What's wrong with my code, and what would be a more efficient way to solve this problem?
public static boolean hasRange(int [] givenNums, int[] range) {
boolean result = true;
int n = range.length;
for (int i = 1; i <= n; i++) {
if (Arrays.asList(givenNums).containsAll(Arrays.asList(range)) == false) {
result = false;
}
}
return result;
}
(I'm pretty sure I'm supposed to do this manually rather than using the containsAll method, so if anyone knows how to solve it that way it would be especially helpful!)
Here's where this method is implicated for anyone who is curious:
public static void checkMatrix(int[][] intMatrix) {
File numberFile = new File("valid3x3") ;
intMatrix= readMatrix(numberFile);
int nSquared = sideLength * sideLength;
int[] values = new int[nSquared];
int[] range = new int[nSquared];
int valCount = 0;
for (int i = 0; i<sideLength; i++) {
for (int j=0; j<sideLength; j++) {
values[valCount] = intMatrix[i][j];
valCount++;
}
}
for (int i=0; i<range.length; i++) {
range[i] = i+1;
}
Boolean valuesThere = hasRange(values, range);
valuesThere is false when printed.
First style:
if (condition == false) // Works, but at the end you have if (true == false) or such
if (!condition) // Better: not condition
// Do proper usage, if you have a parameter, do not read it in the method.
File numberFile = new File("valid3x3") ;
intMatrix = readMatrix(numberFile);
checkMatrix(intMatrix);
public static void checkMatrix(int[][] intMatrix) {
int nSquared = sideLength * sideLength;
int[] values = new int[nSquared];
Then the problem. It is laudable to see that a List or even better a Set approach is the exact abstraction level: going into detail not sensible. Here however just that is wanted.
To know whether every element in a range [1, ..., n] is present.
You could walk through the given numbers,
and for every number look whether it new in the range, mark it as no longer new,
and if n new numbers are reached: return true.
int newRangeNumbers = 0;
boolean[] foundRangeNumbers = new boolean[n]; // Automatically false
Think of better names.
You say you have a one dimensional array right?
Good. Then I think you are thinking to complicated.
I try to explain you another way to check if all numbers in an array are in number order.
For instance you have the array with following values:
int[] array = {9,4,6,7,8,1,2,3,5,8};
First of all you can order the Array simpel with
Arrays.sort(array);
After you've done this you can loop through the array and compare with the index like (in a method):
for(int i = array[0];i < array.length; i++){
if(array[i] != i) return false;
One way to solve this is to first sort the unsorted int array like you said then run a binary search to look for all values from 1...n. Sorry I'm not familiar with Java so I wrote in pseudocode. Instead of a linear search which takes O(N), binary search runs in O(logN) so is much quicker. But precondition is the array you are searching through must be sorted.
//pseudocode
int range[N] = {1...n};
cnt = 0;
while(i<-inputStream)
int unsortedArray[cnt]=i
cnt++;
sort(unsortedArray);
for(i from 0 to N-1)
{
bool res = binarySearch(unsortedArray, range[i]);
if(!res)
return false;
}
return true;
What I comprehended from your description is that the array is not necessarily sorted (in order). So, we can try using linear search method.
public static void main(String[] args){
boolean result = true;
int[] range <- Contains all the numbers
int[] givenNums <- Contains the numbers to check
for(int i=0; i<givenNums.length; i++){
if(!has(range, givenNums[i])){
result = false;
break;
}
}
System.out.println(result==false?"All elements do not exist":"All elements exist");
}
private static boolean has(int[] range, int n){
//we do linear search here
for(int i:range){
if(i == n)
return true;
}
return false;
}
This code displays whether all the elements in array givenNums exist in the array range.
Arrays.asList(givenNums).
This does not do what you think. It returns a List<int[]> with a single element, it does not box the values in givenNums to Integer and return a List<Integer>. This explains why your approach does not work.
Using Java 8 streams, assuming you don't want to permanently sort givens. Eliminate the copyOf() if you don't care:
int[] sorted = Arrays.copyOf(givens,givens.length);
Arrays.sort(sorted);
boolean result = Arrays.stream(range).allMatch(t -> Arrays.binarySearch(sorted, t) >= 0);
public static boolean hasRange(int [] givenNums, int[] range) {
Set result = new HashSet();
for (int givenNum : givenNums) {
result.add(givenNum);
}
for (int num : range) {
result.add(num);
}
return result.size() == givenNums.length;
}
The problem with your code is that the function hasRange takes two primitive int array and when you pass primitive int array to Arrays.asList it will return a List containing a single element of type int[]. In this containsAll will not check actual elements rather it will compare primitive array object references.
Solution is either you create an Integer[] and then use Arrays.asList or if that's not possible then convert the int[] to Integer[].
public static boolean hasRange(Integer[] givenNums, Integer[] range) {
return Arrays.asList(givenNums).containsAll(Arrays.asList(range));
}
Check here for sample code and output.
If you are using ApacheCommonsLang library you can directly convert int[] to Integer[].
Integer[] newRangeArray = ArrayUtils.toObject(range);
A mathematical approach: if you know the max value (or search the max value) check the sum. Because the sum for the numbers 1,2,3,...,n is always equal to n*(n+1)/2. So if the sum is equal to that expression all values are in your array and if not some values are missing. Example
public class NewClass12 {
static int [] arr = {1,5,2,3,4,7,9,8};
public static void main(String [] args){
System.out.println(containsAllValues(arr, highestValue(arr)));
}
public static boolean containsAllValues(int[] arr, int n){
int sum = 0;
for(int k = 0; k<arr.length;k++){
sum +=arr[k];
}
return (sum == n*(n+1)/2);
}
public static int highestValue(int[]arr){
int highest = arr[0];
for(int i = 0; i < arr.length; i++) {
if(highest<arr[i]) highest = arr[i];
}
return highest;
}
}
according to this your method could look like this
public static boolen hasRange (int [] arr){
int highest = arr[0];
int sum = 0;
for(int i = 0; i < arr.length; i++) {
if(highest<arr[i]) highest = arr[i];
}
for(int k = 0; k<arr.length;k++){
sum +=arr[k];
}
return (sum == highest *(highest +1)/2);
}

Java Equivalent for Numpy.arange [duplicate]

Does Java have an equivalent to Python's range(int, int) method?
Old question, new answer (for Java 8)
IntStream.range(0, 10).forEach(n -> System.out.println(n));
or with method references:
IntStream.range(0, 10).forEach(System.out::println);
Guava also provides something similar to Python's range:
Range.closed(1, 5).asSet(DiscreteDomains.integers());
You can also implement a fairly simple iterator to do the same sort of thing using Guava's AbstractIterator:
return new AbstractIterator<Integer>() {
int next = getStart();
#Override protected Integer computeNext() {
if (isBeyondEnd(next)) {
return endOfData();
}
Integer result = next;
next = next + getStep();
return result;
}
};
I'm working on a little Java utils library called Jools, and it contains a class Range which provides the functionality you need (there's a downloadable JAR).
Constructors are either Range(int stop), Range(int start, int stop), or Range(int start, int stop, int step) (similiar to a for loop) and you can either iterate through it, which used lazy evaluation, or you can use its toList() method to explicitly get the range list.
for (int i : new Range(10)) {...} // i = 0,1,2,3,4,5,6,7,8,9
for (int i : new Range(4,10)) {...} // i = 4,5,6,7,8,9
for (int i : new Range(0,10,2)) {...} // i = 0,2,4,6,8
Range range = new Range(0,10,2);
range.toList(); // [0,2,4,6,8]
Since Guava 15.0, Range.asSet() has been deprecated and is scheduled to be removed in version 16. Use the following instead:
ContiguousSet.create(Range.closed(1, 5), DiscreteDomain.integers());
You can use the following code snippet in order to get a range set of integers:
Set<Integer> iset = IntStream.rangeClosed(1, 5).boxed().collect
(Collectors.toSet());
public int[] range(int start, int stop)
{
int[] result = new int[stop-start];
for(int i=0;i<stop-start;i++)
result[i] = start+i;
return result;
}
Forgive any syntax or style errors; I normally program in C#.
public int[] range(int start, int length) {
int[] range = new int[length - start + 1];
for (int i = start; i <= length; i++) {
range[i - start] = i;
}
return range;
}
(Long answer just to say "No")
Java 9 - IntStream::iterate
Since Java 9 you can use IntStream::iterate and you can even customize the step. For example if you want int array :
public static int[] getInRange(final int min, final int max, final int step) {
return IntStream.iterate(min, i -> i < max, i -> i + step)
.toArray();
}
or List :
public static List<Integer> getInRange(final int min, final int max, final int step) {
return IntStream.iterate(min, i -> i < max, i -> i + step)
.boxed()
.collect(Collectors.toList());
}
And then use it :
int[] range = getInRange(0, 10, 1);
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());
Groovy's nifty Range class can be used from Java, though it's certainly not as groovy.
The "Functional Java" library allows to program in such a way to a limited degree, it has a range() method creating an fj.data.Array instance.
See:
http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/data/Array.html#range%28int,%20int%29
Similarly the "Totally Lazy" library offers a lazy range method:
http://code.google.com/p/totallylazy/
I know this is an old post but if you are looking for a solution that returns an object stream and don't want to or can't use any additional dependencies:
Stream.iterate(start, n -> n + 1).limit(stop);
start - inclusive
stop - exclusive
If you mean to use it like you would in a Python loop, Java loops nicely with the for statement, which renders this structure unnecessary for that purpose.
Java 8
private static int[] range(int start, int stop, int step) {
int[] result = new int[(stop-start)%step == 0 ? (stop-start)/step : (stop-start)/step+1];
int count = 0;
Function<Integer, Boolean> condition = step > 0 ? (x) -> x < stop : (x) -> x > stop;
for (int i = start; condition.apply(i); i += step) {
result[count] = i;
count++;
}
return result;
}

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]

How to get maximum value from the Collection (for example ArrayList)?

There is an ArrayList which stores integer values. I need to find the maximum value in this list. E.g. suppose the arrayList stored values are : 10, 20, 30, 40, 50 and the max
value would be 50.
What is the efficient way to find the maximum value?
#Edit : I just found one solution for which I am not very sure
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(100); /* add(200), add(250) add(350) add(150) add(450)*/
Integer i = Collections.max(arrayList)
and this returns the highest value.
Another way to compare the each value e.g. selection sort or binary sort algorithm
You can use the Collections API to achieve what you want easily - read efficiently - enough
Javadoc for Collections.max
Collections.max(arrayList);
Returns the maximum element of the given collection, according to the natural ordering of its elements. All elements in the collection must implement the Comparable interface.
This question is almost a year old but I have found that if you make a custom comparator for objects you can use Collections.max for an array list of objects.
import java.util.Comparator;
public class compPopulation implements Comparator<Country> {
public int compare(Country a, Country b) {
if (a.getPopulation() > b.getPopulation())
return -1; // highest value first
if (a.getPopulation() == b.Population())
return 0;
return 1;
}
}
ArrayList<Country> X = new ArrayList<Country>();
// create some country objects and put in the list
Country ZZ = Collections.max(X, new compPopulation());
public int getMax(ArrayList list){
int max = Integer.MIN_VALUE;
for(int i=0; i<list.size(); i++){
if(list.get(i) > max){
max = list.get(i);
}
}
return max;
}
From my understanding, this is basically what Collections.max() does, though they use a comparator since lists are generic.
We can simply use Collections.max() and Collections.min() method.
public class MaxList {
public static void main(String[] args) {
List l = new ArrayList();
l.add(1);
l.add(2);
l.add(3);
l.add(4);
l.add(5);
System.out.println(Collections.max(l)); // 5
System.out.println(Collections.min(l)); // 1
}
}
Integer class implements Comparable.So we can easily get the max or min value of the Integer list.
public int maxOfNumList() {
List<Integer> numList = new ArrayList<>();
numList.add(1);
numList.add(10);
return Collections.max(numList);
}
If a class does not implements Comparable and we have to find max and min value then we have to write our own Comparator.
List<MyObject> objList = new ArrayList<MyObject>();
objList.add(object1);
objList.add(object2);
objList.add(object3);
MyObject maxObject = Collections.max(objList, new Comparator<MyObject>() {
#Override
public int compare(MyObject o1, MyObject o2) {
if (o1.getValue() == o2.getValue()) {
return 0;
} else if (o1.getValue() > o2.getValue()) {
return -1;
} else if (o1.getValue() < o2.getValue()) {
return 1;
}
return 0;
}
});
Comparator.comparing
In Java 8, Collections have been enhanced by using lambda. So finding max and min can be accomplished as follows, using Comparator.comparing:
Code:
List<Integer> ints = Stream.of(12, 72, 54, 83, 51).collect(Collectors.toList());
System.out.println("the list: ");
ints.forEach((i) -> {
System.out.print(i + " ");
});
System.out.println("");
Integer minNumber = ints.stream()
.min(Comparator.comparing(i -> i)).get();
Integer maxNumber = ints.stream()
.max(Comparator.comparing(i -> i)).get();
System.out.println("Min number is " + minNumber);
System.out.println("Max number is " + maxNumber);
Output:
the list: 12 72 54 83 51
Min number is 12
Max number is 83
There is no particularly efficient way to find the maximum value in an unsorted list -- you just need to check them all and return the highest value.
Here are three more ways to find the maximum value in a list, using streams:
List<Integer> nums = Arrays.asList(-1, 2, 1, 7, 3);
Optional<Integer> max1 = nums.stream().reduce(Integer::max);
Optional<Integer> max2 = nums.stream().max(Comparator.naturalOrder());
OptionalInt max3 = nums.stream().mapToInt(p->p).max();
System.out.println("max1: " + max1.get() + ", max2: "
+ max2.get() + ", max3: " + max3.getAsInt());
All of these methods, just like Collections.max, iterate over the entire collection, hence they require time proportional to the size of the collection.
Java 8
As integers are comparable we can use the following one liner in:
List<Integer> ints = Stream.of(22,44,11,66,33,55).collect(Collectors.toList());
Integer max = ints.stream().mapToInt(i->i).max().orElseThrow(NoSuchElementException::new); //66
Integer min = ints.stream().mapToInt(i->i).min().orElseThrow(NoSuchElementException::new); //11
Another point to note is we cannot use Funtion.identity() in place of i->i as mapToInt expects ToIntFunction which is a completely different interface and is not related to Function. Moreover this interface has only one method applyAsInt and no identity() method.
In Java8
arrayList.stream()
.reduce(Integer::max)
.get()
Here is the fucntion
public int getIndexOfMax(ArrayList<Integer> arr){
int MaxVal = arr.get(0); // take first as MaxVal
int indexOfMax = -1; //returns -1 if all elements are equal
for (int i = 0; i < arr.size(); i++) {
//if current is less then MaxVal
if(arr.get(i) < MaxVal ){
MaxVal = arr.get(i); // put it in MaxVal
indexOfMax = i; // put index of current Max
}
}
return indexOfMax;
}
package in.co.largestinarraylist;
import java.util.ArrayList;
import java.util.Scanner;
public class LargestInArrayList {
public static void main(String[] args) {
int n;
ArrayList<Integer> L = new ArrayList<Integer>();
int max;
Scanner in = new Scanner(System.in);
System.out.println("Enter Size of Array List");
n = in.nextInt();
System.out.println("Enter elements in Array List");
for (int i = 0; i < n; i++) {
L.add(in.nextInt());
}
max = L.get(0);
for (int i = 0; i < L.size(); i++) {
if (L.get(i) > max) {
max = L.get(i);
}
}
System.out.println("Max Element: " + max);
in.close();
}
}
In addition to gotomanners answer, in case anyone else came here looking for a null safe solution to the same problem, this is what I ended up with
Collections.max(arrayList, Comparator.nullsFirst(Comparator.naturalOrder()))
model =list.stream().max(Comparator.comparing(Model::yourSortList)).get();
They're many ways to find the maximum. But there will be no noticeable difference in performance unless the collection is huge.
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(
integers.stream().max(Integer::compare).get()
);
System.out.println(
integers.stream().mapToInt(Integer::intValue).max().getAsInt()
);
System.out.println(
integers.stream().max(Comparator.comparing(i -> i)).get()
);
System.out.println(
integers.stream().reduce((a, b) -> a > b ? a : b).get()
);
System.out.println(
integers.stream().reduce(Integer.MIN_VALUE, (a, b) -> a > b ? a : b)
);
The max method expects a Comparator as a parameter.
The reduce method expects a BinaryOperator as a parameter.
depending on the size of your array a multithreaded solution might also speed up things

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