Creating an array of numbers without looping? - java

Okay so I am using the JavaMail library and I am trying to fetch certain message numbers. I want to do it efficiently and not have to loop twice over something… Anyways my question to you is: How can I create an array that starts at index x and ends at index x - 11 without looping?

If you want to create and populate an array, you have basically three options:
Write the values explicitly: int[] nums = new int[] { 0, 1, 2, 3, 4, ... }
Use some form of for-loop: for (int i = 0; i < 10; i++) { nums[i] = i; }
Create it recursively:
int[] nums = new int[12];
nums = populate(0, x, nums);
private int[] populate(int index, int x, int[] nums) {
if (nums.length >= index) {
return nums;
} else {
nums[index] = x - index; // x-0 through x-11
return populate(index+1, x, nums);
}
}
Vanilla Java, without extra libraries and whatnot, doesn't support a map function which would allow you to specify a function that would somehow auto-generate your values.
Though, I really don't understand why you don't want to use a loop, especially for something trivial like this.

int[] myArray = new int[] {x, x-1, x-2, x-3, x-4, x-5, x-6, x-7, x-8, x-9, x-10, x-11};

Since JDK 8 it's possible to populate an array using streams instead of for loops.
For example, an array of numbers x through x-11 can be generated using IntStream.iterate() which applies the specified function to every previous element to obtain the next one, in this case decrement.
int x = 55;
int[] arrayOfNumbers = IntStream
.iterate(x, previousNumber -> --previousNumber)
.limit(11)
.toArray();
// Creates an array containing: [55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45]

Related

sumUp each array of an multidimensional array

I want to sum up each i array and store it as an element of a new array.
I expect to get int[] sumUp={10,30}
What am I doing wrong?
My result is instead {0,10}
int[][] matrixOne= {{1,2,3,4},{10,20}};
int [] sumUp=new int[matrixOne.length];
int toSum=0;
for(int i=0;i<matrixOne.length;i++) {
sumUp[i]=toSum;
for(int j=0;j<matrixOne[i].length;j++) {
toSum+=matrixOne[i][j];
}
}
System.out.println(Arrays.toString(sumUp));
You're storing the result before you sum the numbers.
EDIT: forgot to reset the sum
toSum = 0;
for(int j=0;j<matrixOne[i].length;j++) {
toSum+=matrixOne[i][j];
}
sumUp[i]=toSum;
I would prefer a stream on the int[][] which you can map (and stream() to sum()) in one pass. Like,
int[][] matrixOne = { { 1, 2, 3, 4 }, { 10, 20 } };
int[] sumUp = Arrays.stream(matrixOne).mapToInt(x -> Arrays.stream(x).sum()).toArray();
System.out.println(Arrays.toString(sumUp));
Outputs (as expected)
[10, 30]
As the others are pointing out you are storing your sum in toSum not sumUp in your inner loop.
If you want to avoid these mistakes, and you are using Java 8, you could simply do something like:
int[][] matrixOne= {{1,2,3,4},{10,20}};
int [] sumUp=new int[matrixOne.length];
for(int i=0;i<matrixOne.length;i++) {
sumUp[i] = Arrays.stream(matrixOne[i]).sum();
}
You could even stream and map the outer array, but it becomes a bit more complicated.

How to copy only certain elements of one Array to another in Java

I am struggling to create an array with the correct size according to my parameters I have set up. Long story short this program is dealing with a set number of elements in the first array. Those elements are as follows
int [] myWeights = {258, 58, 209, 91, 79, 182, 172, 27, 7, 29, 128, 198};
Now those elements are in ounces. I get the program to run everything correctly, now my professor wants us to separate the ones that are over 8 pounds into a new array. Those elements in the new array in this case are 258, 209, 182, 172, and 198. The problem is that the program, at the beginning, can create a randomly sized array with varying sized elements between the numbers 1-320. Is there a way to have some sort of loop instantiate the proper amount of "boxes" needed. Or am I just supposed to instantiate some arbitrary number and hope that is what I will need? My current code for this is
public static int [] overGivenPounds(int x, int [] array){
int pounds = 0;
int arrayLength = 0;
int arrayOverEightPounds[];
int k = 0;
for(int i = 0; i < array.length; i++){
pounds = array[i] / 16;
if(x < pounds){
arrayOverEightPounds[k] = array[i];
k++;
}
}
return arrayOverEightPounds;
If any of this seems unclear please ask, there is no need to be rude. I am very new to Java.
Use a loop to determine the size of the target array
Create the target array of the needed size
Use a second loop to put values in the target array
Without that first step, you cannot know the right size of the array. If you create an array that's even one element too small or one element two big, that will be a waste,
because you will be forced to create a 3rd array to return an array of the right size.
So your solution should look something like:
public static int[] overGivenPounds(int x, int[] array) {
int size = 0;
for (int value : array) {
if (satisfies(x, value)) {
size++;
}
}
int[] result = new int[size];
// ??? -> for you to complete this
for (int value : array) {
if (satisfies(x, value)) {
// ??? -> for you to complete this
}
}
return result;
}
public static int[] overGivenPounds(int x, int[] array){
Arrays.sort(array);
boolean foundSomething = false;
int startIndex = 0;
for (int i = 0; i < array.length; i++) {
if(array[i]/16>=x){
startIndex = i;
foundSomething = true;
break;
}
}
if(foundSomething)
return Arrays.copyOfRange(array, startIndex, array.length);
return null;
}
Are you allowed to use Java streams? If so, the solution would be:
return Arrays.stream(myWeights).filter(n -> n/16 > x).toArray();
If not then you could use Arrays.copyOfto create an array of the correct length:
int[] heavyWeights = int[myWeights.length];
int size = 0;
for (int weight: myWeights)
if (weight / 16 > x)
heavyWeights[size++] = weight;
return Arrays.copyOf(heavyWeights, size);
Are you allowed to use other classes? If so, you could just use an ArrayList and then use
//int arrayOverEightPounds[];
List<Integer> listOverEightPounds = new ArrayList<>();
//...
//arrayOverEightPounds[k] = array[i];
listOverEightPounds.add(array[i]);
//....
return listOverEightPounds.toArray(new Integer[0]);
to return an array of the proper size. In this case you can get rid of k. ArrayList uses an array internally but will resize it automatically if it needs more space so you don't have to do that micro-management. The toArray method on ArrayList will return a new array of the proper size if the array that's passed in is not big enough. A common thing you see is to just pass in an array of size 0 into toArray which means the returned value will always be the correctly sized array.
The usual way to do it is to create an array that you know can hold everything, add your items to that array, while keeping track of how many items you have added. At the end you return a copy of the array, truncated to the number of items.
Or, with Java 8, you can write it as a stream one-liner:
return Arrays.stream(array).filter(i -> (i / 16) > x).toArray();

Trying to Print Array without Repeating Numbers

I have a programming assignment where I am tasked with the following:
I am taking two int values (x and y) and creating two different arrays: the first (size x) will print an array starting from x and descending down to 1. The second (size y) will take random values from the first array (size x) and store it in its own array. I will then print out the second array. However, the second array cannot have any repeating values. For example, if the array was size 10, it could not have two of the same digit within its 10 individual indexes. I am attempting to store unique elements in my second array by creating two arrays, one boolean to check for unique elements and another one to store those unique elements. Here is my code:
/*
* user will enter desired size x for first array labeled arr_1
* arr_1 will contain values descending from x down to 1
* user will enter desired size y for second array labeled arr_2
* arr_2 will contain random values taken from arr_1 w/o repeating numbers
*/
import java.util.Arrays;
// import java.util.Arrays;
import java.util.Random;
// import java.util.Scanner;
public class Prog1B
{
public static void main(String[] args)
{
System.out.println("Program 1B, Christopher Moussa, masc1574");
// Scanner scnr = new Scanner(System.in);
int x = 20;
int v = x;
int[] arr_1 = new int[x];
for (int i = x-1; i >= 0; i--)
{
arr_1[i] = v; // System.out.print(i+1 + " "); prints 20, 19, ... , 1
v--; // System.out.print(arr_1[i] + " "); prints 20, 19, ... , 1
}
// int[] b = unique(arr_1);
System.out.println(Arrays.toString(unique(arr_1)));
}
public static int[] unique (int[] n)
{
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
unique[i] = n[index];
}
return unique;
}
}
The code compiles and runs, but it still prints out an array with repeating values. I am trying to write the program so that it does not print out an array with repeating values, only unique values. Do you have any suggestions as to where the problem lies? I am pretty sure it lies within the "unique" method, more specifically when the boolean array is checking for unique values (I noticed while trying to debug that even if the random index it generated was not unique, it still skipped the while condition and printed it out). I am a beginning programmer (a freshman at San Diego State studying computer science) and any feedback/advice will be greatly appreciated. Thanks you very much.
I found the problem in your code. You never update your "seen" Boolean array. See the code below for fix:
public static int[] unique (int[] n){
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
seen[index] = true; //boolean array updated
unique[i] = n[index];
}
return unique;
}
Using this fix, I was able to get the output below (which has no repeats):
[3, 11, 17, 10, 16, 18, 15, 6, 14, 20, 7, 13, 1, 19, 9, 2, 5, 4, 12, 8]
You need to even set your array seen[index] = true;
public static int[] unique (int[] n)
{
boolean[] seen = new boolean[n.length];
int[] unique = new int[n.length];
Random rand = new Random(123L);
for (int i = 0; i < n.length; i++)
{
int index = rand.nextInt(n.length);
while (seen[index])
{
index = rand.nextInt(n.length);
}
unique[i] = n[index];
seen[index] = true;
}
return unique;
}
Unless you specifically have to do it this way, I suggest you take a step back and try a totally different approach, something like this:
Set<int> mySet = new HashSet<int>(Arrays.asList(someArray));
NOTE: You will want to adjust the return type of unique() to be Set
The rest of the implementation is left as an excercise for the reader. Basically you take the array and convert it to a set as the example above.
(Credit where credit is due)
I just wanted to steer you in the right direction per https://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions
Good luck, I would say the biggest lesson here is how to walk away from code that has become inefficient when a better solution exists. Good luck!
Heres is how to do this using java8 lambdas
ArrayList<Integer> arrayli = new ArrayList<Integer>(Arrays.asList(arr_1));//converted array to list
System.out.println();
List<Integer> distinctIntegers = arrayli.stream().
.distinct()
.boxed()
.collect(Collectors.toList());
distinctIntegers.foreach(System.out::println);

Index an array by an array in java

In R you can do something like this:
> x = c(1, 222, 333, 4, 5)
> x[c(2, 3)]
[1] 222 333
> in the beginning of line is just a prompt in an interactive session. x is a vector of numeric values, and if you want the 2nd and 3rd element of x, you pass another vector c(2, 3) to index x. This is different from Arrays.copyOfRange in java: you can pass an arbitrary index vector to x, not necessarily in a continuous range, i.e. x[c(1,3,5)]
I am wondering if there is a similar feature in java.
As I understood your question, you could create a method that take a list of indexes as parameters.
For generic arrays, you'll need to use Array.newInstance and cast the resulting array to T[] (thanks and kudos for #Radiodef for pointing this out)
//for lists
static <T> List<T> buildList(List<T> original, int... indexes){
List<T> finalList = new ArrayList<>();
for(int index : indexes){
finalList.add(original.get(index));
}
return finalList;
}
//for arrays
static <T> T[] buildArray (T[] original, int... indexes){
#SuppressWarnings("unchecked")
T[] finalArray = (T[])Array.newInstance(original.getClass().getComponentType(), indexes.length);
for(int i = 0; i < indexes.length; i++){
finalArray[i] = original[indexes[i]];
}
return finalArray;
}
Few notes :
For primitive arrays (like int[] or double[]), you'll have to overload the methods, that's why I suggest you to use a List with generics instead.
Indexes for arrays in Java are 0 based (starts from 0 to length-1)
Don't forget to add additional checks for the method (valid index, original list or index not null)
If you use a LinkedList instead of an ArrayList, be aware that #get(int index) is an O(n) operation instead of O(1)
Example of usage :
public static void main(String[] args) {
Integer[] xArray = {-1, 10, 24, 7};
List<Integer> xList = Arrays.asList(-1, 10, 24, 7);
System.out.println(Arrays.toString(buildArray(xArray, 0, 2)));
System.out.println(buildList(xList, 0, 1, 3));
}
Which outputs:
[-1, 24]
[-1, 10, 7]
take a look at Arrays.copyOfRange

Java element-wise sum 2 arrays

Given that I have two arrays in Java, A and B I want to add the elements, element-wise, which results in a sum array. Doing this implicitly with a loop is easy but I was wondering if there was a more elegant solution, perhaps with the guava collections or build in java utils. Or perhaps a python-ish way which makes is easy with list comprehensions.
Example:
A = [2,6,1,4]
B = [2,1,4,4]
sum = [4,7,5,8]
You can do it like this:
private void sum() {
int a[] = {2, 6, 1, 4};
int b[] = {2, 1, 4, 4};
int result[] = new int[a.length];
Arrays.setAll(result, i -> a[i] + b[i]);
}
This will first create int result[] of the correct size.
Then with Java 8, released yesterday, the easy part comes:
You can do an Arrays.setAll(int[] array, IntUnaryOperator);
As IntUnaryOperator you can create a lambda mapping the index to the result, in here we choose to map i to a[i] + b[i], which exactly produces our sum.
For very big arrays we can even use Arrays.parallelSetAll
You can use java8 stream and operation on array like this:
//in this example a[] and b[] are same length
int[] a = ...
int[] b = ...
int[] result = new int[a.length];
IntStream.range(0, a.length)
.forEach(i -> result[i] = a[i] + b[i]);
The answer in java8

Categories