Java Equivalent for Numpy.arange [duplicate] - java

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;
}

Related

Do I need to create stream for generating a list in range?

I am new in Java Stream API and trying to solve some exercises. In a problem, I need to return the odd numbers as a List<Integer> with the given range. First, I used a loop as shown below:
public static List<Integer> oddNumbers(int l, int r) {
List<Integer> list = new ArrayList<>();
for (int i = l; i <= r; i++) {
if (i % 2 != 0) {
list.add(i);
}
}
return list;
}
Then I thought that maybe it is better using stream in order to provide a cleaner solution. But it is not working when I tried with filter and anyMatch.
public static List<Integer> oddNumbers(int l, int r) {
return IntStream.range(l,r)
.filter(x -> x % 2 != 0)
// .anyMatch(x -> x % 2 == 0)
.collect(Collectors.toList());
}
So:
1. How can I make it work using stream?
2. Should I prefer the second approach as it seems to be cleaner?
Like this:
public static List<Integer> oddNumbers(final int l, final int r) {
return IntStream.range(l, r + 1).filter(i -> i % 2 != 0).boxed().toList();
}
It is a matter of taste, but one could argue that the intent is more clear using the stream API.
(toList() is new from Java 16, otherwise one have to use collect(Collectors.toList())

Common method to find index of max element in both Float and Integer array

This is basically to avoid redundant code. I have two different arrays, one of Float type and one Integer type. I need to find index of maximum element in both the arrays which is easy to do as I can write two different methods, one for comparing float and one for comparing Integers.
What am trying to do improve is to write just one common method which can take in either of the array as argument and can return me the max index. What I have tried unsuccessfully so far is:
private static int findMaxIndex(Object [] arr){
int maxIndex =(int) IntStream.range(0,arr.length)
.boxed()
.max(Comparator.comparingInt(i -> arr[i])) // getting compiler error here
.map(max->arr[max])
.orElse(-1);
return maxIndex;
}
and am looking to call this method like this:
Float [] a = {0.3f, 0.5f, 0.9f, 0.7f, 0.1f};
Integer []b = {3000, 250, 100, 2000, 2000, 10246};
int maxIndexFloatArray = findMaxIndex(a);
int maxIndexIntegerArray = findMaxIndex(b);
Am pretty sure there are easier ways to do this, but am a bit rusty now in hands on java code. Hope this explains the question correctly.
lambda with reduce comparing Comparables
private static <T extends Comparable<? super T>> int findMaxIndex(T[] arr) {
return IntStream.range(0, arr.length)
.reduce((l, r) -> arr[l].compareTo(arr[r]) < 0 ? r : l).orElse(-1);
}
for multiple max values the index of the first is returned
if You need the index of the last max value change the < to <=
arr can be empty but may not contain null values
You could do it old fashioned:
private <T> int findMaxIndex(T[] arr, Comparator<T> comparator){
int maxIndex= 0;
T currMax = arr[0];
for (int i=1;i<arr.length;i++){
if (comparator.compare(currMax,arr[i])<0){
currMax = arr[i];
maxIndex = i;
}
}
return maxIndex;
}
And then call it like:
private int getMaxFloatIndex(Float[] floatArr){
return findMaxIndex(floatArr,Float::compareTo);
}
Grabbing the inheritance hierarchy "from top", I would propose Comparable<X> as the input type for findMaxIndex. It is the most general type of object, of which you can distinguish a "max element":
private static <X extends Comparable<X>> int findMaxIndex(final X[] arr) {
return IntStream.range(0, arr.length)
.boxed()
.max(
(Integer idx1, Integer idx2) -> arr[idx1].compareTo(arr[idx2])
)
.orElse(-1);
}
For simplicity: Hoping/assuming arr is nor null nor contains null elements! ;) (otherwise: NPE!)
...to use it like:
Float[] a = { 0.3f, 0.5f, 0.9f, 0.7f, 0.1f };
Integer[] b = { 3000, 250, 100, 2000, 2000, 10246 };
System.out.println(findMaxIndex(a));
System.out.println(findMaxIndex(b));
Prints:
2
5
This one should do the trick:
private static <T extends Number & Comparable<T>> int findMaxIndex(T[] array) {
if (array == null || array.length == 0) return -1;
int largest = 0;
for (int i = 1; i < array.length; i++) {
if (array[i].compareTo(array[largest]) > 0) largest = i;
}
return largest;
}
You literally tell the compiler that your generic parameter T should be both a Number and Comparable to the same type.
<T extends Number & Comparable<T>> int findMaxIndex(T[] arr)
This can find the index of the maximal value based on Number, the interface of all numeric types, wrapper classes and atomic wrappers.
Also a findMax might so be made. Without the numeric aspect, just Comparable suffices, say for a String[].

Get missing number from int array with Java streams

I have following array,
int [] a = {5,3,10,8,4,2,9,6};
I am trying get the missing number from tha array,
private static int getMissingNumber(int[] a) {
int expectedSum = IntStream.rangeClosed(1, 10)
.reduce(0, Integer::sum);
int actualSum = Arrays.stream(a).reduce(0, Integer::sum);
return expectedSum-actualSum;
}
But is getting 8 instead of 7. What am I missing here?
You minimal value is 2 so should be the start of the range IntStream.rangeClosed(2, 10)
Also you can directly call .sum() on IntStream
private static int getMissingNumber(int[] a) {
return IntStream.rangeClosed(2, 10).sum() - Arrays.stream(a).sum();
}
The sum of the numbers from 1 to 10 Is 10 * (10+1) / 2 = 55. You are missing 1 and 7, so the sum of the missing numbers is 8. Looks right to me.
You need to use 2 instead of 1 ,
IntStream.rangeClosed(2, 10)
You can also find min and max elements in the array using summaryStatistics(),
private static int getMissingNumber(int[] a) {
IntSummaryStatistics summaryStatistics = Arrays.stream(a).summaryStatistics();
int expectedSum = IntStream.rangeClosed(summaryStatistics.getMin(), summaryStatistics.getMax())
.sum();
int actualSum = (int) summaryStatistics.getSum();
return expectedSum-actualSum;
}

Java refactoring code smells

I was given feedback that I need to improve my refactoring/eleminating code smells skills.
I need short exercises to detect and how-to improve the most comon code smells
with answers in java
example:
public class Calculator {
public long sum(int min, int max) {
long result = 0;
for (int i = min ; i <= max ; i++)
result += i;
return result;
}
public long sumOfSquares(int min, int max) {
long result = 0;
for (int i = min ; i <= max ; i++)
result += i * i;
return result;
}
}
and then the best/most convinent solution.
BTW, you could right away show me best solution for this repetition over there /\ maybe with use of operator lambda "->"
Thanks!
You could try merging both methods in one. Since both of them look like
public long sum(long min, long max) {
long result = 0;
for (int i = min ; i <= max ; i++)
result += someOperation(i);
return result;
}
you could allow user to provide some operation which will compute i, so it can be i or i+2 or i*i.
Such strategy can be implementation of LongUnaryOperator interface where user will need to implement long applyAsLong(long operand) method.
So instead of two methods you can have one which can look like
public static long sum(long min, long max, LongUnaryOperator mapper) {
long result = 0;
for (long i = min ; i <= max ; i++)
result += mapper.applyAsLong(i);
return result;
}
and you could use it like
sum(1, 4, i -> i * i)//sum of squares
i->i*i is lambda expression which implements functional interface LongUnaryOperator and provides implementation of its abstract applyAsLong method which will be used in our code. In other words it will map i to i*i.
more usage examples:
sum(1, 4, i -> 2 * i)//sum of doubled values
sum(1, 4, i -> i)//sum of original values
//i->i can be also returned with `LongUnaryOperator.identity()`
//so you can rewrite your code into something like
sum(1, 4, LongUnaryOperator.identity())
You can also rewrite your code using streams like
public static long sum(long min, long max, LongUnaryOperator mapper) {
return LongStream.rangeClosed(min, max).map(mapper).sum();
}

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

Categories

Resources