I know how to use the for-each loop to cycle through an entire array like so:
for(int d : arrayname){
do something
But how do you use the for-each loop to cycle through a partial array, like the one I am trying to do is to use the for-each to cycle through only the months of May-October, i.e. [4] - [9] to calculate the heat index. Here is a snippet of my code that shows what I am trying to do:
// create array for KeyWestTemp
double[] KeyWestTemp;
KeyWestTemp = new double[12];
// initialize array
KeyWestTemp[0] = 70.3;
KeyWestTemp[1] = 70.8;
KeyWestTemp[2] = 73.8;
KeyWestTemp[3] = 77.0;
KeyWestTemp[4] = 80.7;
KeyWestTemp[5] = 83.4;
KeyWestTemp[6] = 84.5;
KeyWestTemp[7] = 84.4;
KeyWestTemp[8] = 83.4;
KeyWestTemp[9] = 80.2;
KeyWestTemp[10] = 76.3;
KeyWestTemp[11] = 72.0;
// create array for KeyWestHumid
int[] KeyWestHumid;
KeyWestHumid = new int[12];
// initialize array
KeyWestHumid[0] = 69;
KeyWestHumid[1] = 67;
KeyWestHumid[2] = 66;
KeyWestHumid[3] = 64;
KeyWestHumid[4] = 66;
KeyWestHumid[5] = 69;
KeyWestHumid[6] = 67;
KeyWestHumid[7] = 67;
KeyWestHumid[8] = 70;
KeyWestHumid[9] = 69;
KeyWestHumid[10] = 69;
KeyWestHumid[11] = 70;
// for-each loop for calculating heat index of May - October
[0] is January and [11] is December
double[] mayOctober = Arrays.copyOfRange(KeyWestHumid, 4, 9);
and foreach mayOctober to do what you asked.
btw, it is prefered in that case to use conventional loop.
You are using the enhanced for loop, you can just use the regular for loop to achieve what you want
for(int i=START; i<=END;i++){
//do work
}
In your case it would most likely look like
int sumOfHumidity=0
for(int month i=4; i<=9;i++){
sumOfHumidity+=KeyWestHumid[month]
}
and then use sumOfHumidity however you see fit.
Other notes
KeyWestHumid is a variable, as such it should be lowerCamelCase, so
keyWestHumid, the same for keyWestTemp
The hard coding of 4 and 9 is probably undesirable, but without knowing the exact program structure it is hard to advise further than saying using the variables startMonth and endMonth is probably desirable, allowing numberOfMonths to be calculated using the two (which I expect you'll want to create an average from sumOfHumidity)
You can use a normal for loop:
for(int month=4; month<=9; month++){
KeyWestHumid[month].something();
}
You cannot use the enhanced for loop to partially iterate an array.
According to the Java language specification:
The enhanced for statement is equivalent to a basic for statement of
the form:
T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
VariableModifiersopt TargetType Identifier = #a[#i];
Statement
}
You can, as suggested in other answers, either create a new array (or any other collection) which contains only the elements you want to iterate or use a regular for loop.
In Java 8:
double[] array = {1, 6, 7, 3, 3, 1, 2, 8, 9, 7, 3};
Arrays.stream(array, 3, 6).forEach((d) -> {
System.out.println(d);
});
OR
IntStream.range(3, 6).mapToDouble(i -> array[i]).forEach(d -> {
System.out.println(d);
});
You could try getting away from arrays and use Lists.
public void test() {
List<Double> keyWestTemp = new ArrayList(Arrays.asList(70.3, 70.8, 73.8, 77.0, 80.7, 83.4, 84.5, 84.4, 83.4, 80.2, 76.3, 72.0));
System.out.println("Key West Temps: "+keyWestTemp);
System.out.println("Apr-Jun Temps: "+keyWestTemp.subList(3, 6));
keyWestTemp.set(4, 81.6);
System.out.println("Apr-Jun Temps: "+keyWestTemp.subList(3, 6));
}
Obviously you can iterate across the sub-lists as easily as you can print them and they shine-through to the underlying list. i.e. if you change the original list the sub-list also sees the change.
Related
What type of collection structure would be best suited for below structure .
I want to create a rows of start and end positions and wanted to store it as a structure. based on the number of occurrences I want to execute a function .
Example
StartPosition Endposition
1 5
6 9
10 14
15 18
Now I want to store the the values like ( (1,5) , (6,9) , (10,14) , (15,18) )
Now I want to execute a function 4 times as I have 4 occurrences
for (i=1 , i <4 , i ++)
{
f(xyz , Startposition , endposition)
}
I suggest you use create a simple class and a List<> of this class.
public class Range{
private int start;
private int end;
// constructor
// gets and setts
}
And you would use like this:
List<Range> ranges = new ArrayList<>();
ranges.add(new Range(1,5));
ranges.add(new Range(6,9));
...
ranges.add(new Range(x,y));
for(Range range : ranges){
f(xyz, range.getStart(), range.getEnd());
}
As I understand, two dimensional array would do. Do you have any reason why you want a collection here?
Option 1: use Array. This is very simple.
int[] arr = { 1, 5, 6, 9, 10, 14, 15, 18 };
for (int i = 0; i < arr.length; i += 2) {
int start = arr[i];
int end = arr[i + 1];
// payload
}
Option 2: use TreeSet with custom comparator. A little bit more difficult, but code is more clear.
Set<Pair<Integer, Integer>> ranges = new TreeSet<>(Comparator.comparingInt((ToIntFunction<Pair<Integer, Integer>>)Pair::getKey).thenComparingInt(Pair::getValue));
ranges.add(new Pair<>(1, 5));
ranges.add(new Pair<>(6, 9));
ranges.add(new Pair<>(10, 14));
ranges.add(new Pair<>(15, 18));
for (Pair<Integer, Integer> range : ranges) {
int start = range.getKey();
int end = range.getValue();
// payload
}
You can use built in java.awt.Point class to set X,Y values. Stores those objects in either java.util.ArrayList or java.util.LinkedList
This is a peice of my code, i am making a grid of 5x5 with random colors set to each section. I need to set the specified y_loc and x_loc in the list to the color randomly picked except i have not been able to find out how. It should be the second last line that is not operating as id like. I understand that i could do this in much much longer code but it would be nice to do it in less.
//making the map
ArrayList<ArrayList<String>> fullmap = new ArrayList<ArrayList<String>>();
ArrayList<String> y_row_0 = new ArrayList<String>();
ArrayList<String> y_row_1 = new ArrayList<String>();
ArrayList<String> y_row_2 = new ArrayList<String>();
ArrayList<String> y_row_3 = new ArrayList<String>();
ArrayList<String> y_row_4 = new ArrayList<String>();
//adding each row
fullmap.add(y_row_0);
fullmap.add(y_row_1);
fullmap.add(y_row_2);
fullmap.add(y_row_3);
fullmap.add(y_row_4);
Random rn = new Random();
//loop to randomly pick colors then set them to their destined locations
for (int y_loc = 0; y_loc < 6; y_loc++){
for (int x_loc = 0; x_loc < 6; x_loc++){
colorPicked = false;
while (!colorPicked){
int ranNum = rn.nextInt();
if (ranNum ==0){
if (redTot < 5) {
redTot += 1;
fullmap.set(y_loc).set(x_loc, "Red"));
colorPicked = true;
Since you have lists in list here, to set something at a specific location, you'll have to get the inner list and then perform the set on it.
The following should work:
fullmap.get(y_loc).set(x_loc, "Red"));
Also, since you seem to always have a 5x5 matrix, I'd recommend using a double array instead. That'd make that line:
fullmap[x_loc][y_loc] = "Red";
You should have something like this:
fullmap.get(y_loc).set(x_loc, "Red"));
Notice the "get". You are "getting" the list at the y location, which returns an array list, then calling "set" against that array list to set the actual value in the index of the "x_loc" value.
You need to make a couple of changes:
While declaring the sub lists, you need to make sure they have 5 empty/null elements. Otherwise set will throw IndexOutOfBoundsException. E.g. you need to declare the lists like this:
ArrayList<String> y_row_0 = Arrays.asList(new String[5]);//Assuming it will have 5 elements
While setting the element, you first need to get the corresponding sub list, e.g. the following needs to be changed from:
fullmap.set(y_loc).set(x_loc, "Red"));
to
fullmap.get(y_loc).set(x_loc, "Red"));
Others have already discussed the indexing issue. Apart from that, I believe that your conditionals may not be executing as you expect. nextInt() will return a reasonable uniform random number in the range of -2147483648 to 2147483647. You have a 1/2^64 chance of getting a 0. Reduce the random number range to something more reasonable. For example, nextInt(10) will return a random number between 0 and 9.
Furthermore, if the probability is too low, you will not get 5 reds all the time. To guarantee 5 picks and for the sake of computational efficiency, it is better to randomly pick array indices and evaluate whether a color is set or not, such as the following pseudo-code
int redTot = 0;
while ( redTot < 5 ) {
int r = rn.nextInt( 5 );
int c = rn.nextInt( 5 );
String color = fullmap.get( r ).get( c );
if ( color == null ) {
fullmap.get( r ).set( c, "Red" );
redTot++;
}
}
I am trying to add a sequence of letters as Strings to a 2D array. So object [17] goes to endState[0][0]; [18] to endState[0][1] and so forth.
The problem I have is with the outside for loop, which just adds object at [32] to all of the cells in the matrix. Normally I would use an iterator to deal with this when using other collections, however, it is not possible with arrays as far as i am aware (I am a novice as you may have guessed).
String [][] endState = new String[4][4];
for(int i1=17;i1<33;i1++){
for(int r=0;r<endState.length;r++){
for(int c=0;c<endState.length;c++){
endState[r][c] = config.split("")[i1];
}
}
}
Any suggestions on how I can overcome this?
Many thanks.
Do you need something like that ?
String[] configs = config.split("");
String [][] endState = new String[4][4];
int i = 17;
for(int r=0;r<endState.length;r++){
for(int c=0;c<endState.length;c++){
endState[r][c] = configs[i++];
}
}
If you want to turn the letters into a gird you can do.
String[] letters = config.substring(17).split("");
String[][] endState = new String[4][];
for (int i = 0; i < endState.length; i++)
endState[i] = Arrays.copyOf(letters, i * 4, 4);
or you could do
String[][] endState = IntStream.range(0, 4)
.mapToObject(i -> Arrays.copyOf(letters, i * 4, 4))
.toArray(s -> new String[s][]);
If you use Java 8, you can do it as follows:
Arrays.asList(someArray).foreach(item -> {});
or
Arrays.asList(someArray).stream().ANY_STREAM_FUNCTION_HERE
If you want iterate your 2dim array:
Arrays.asList(someArray).foreach(item -> {
Arrays.asList(item).foreach(item2 -> {[Do your job here]})
});
You can do it more Java 7 way:
for(item : Arrays.asList(someArray)) {
...
}
Anyway you can always use Arrays.asList(someArray) to obtain a list from array.
Can you create a line of code, within a while-loop, that will create a new array AND change the array's name with each iteration of the while loop?
Example:
int size = 10;
int name_count = 1;
while(size <= 100)
{
//name_count is changing the name of the array by calling it
// "array1", "array2", etc...
//I know this may not be correct code for changing the name of
// the array, but it is suppose to get the point across.
int[] array(name_count) = new int[size];
for (int i = 0; i <= size; i++)
{ /* Adding numbers to an array */ }
size = size + 5;
name_count++;
}
Identifier names need to be defined at compile time. So you can't explicitly use a different variable name on each iteration of the loop.
Another problem with your pseudo-code is that, if the array were to be declared inside the loop, it would fall out of scope when the loop completes, so there wouldn't be much point.
To do something like this you need to use some collection to hold the arrays, and it would be easier to make them explicit objects instead of just arrays. Something like:
List<List<Integer>> listOfArrays = new ArrayList<List<Integer>>();
while (size <= 100) {
List<Integer> listOfNumbers = new ArrayList<Integer>(size);
/* insert loop here to add numbers to listOfNumber */
size += 5;
name_count += 1;
}
Then you can access each list of numbers using an index into listOfArrays -- equivalent to naming each one with the index, but handled at runtime instead of compile time.
You cannot change the array's name, It will just re-declare the array with each successful loop. (It will be a new blank array.) I think what you are looking for is a two dimensional array.
int[][] myArray = new int[3][3];
Is there a way to do the following at the same time?
static final int UN = 0; // uninitialized nodes
int[] arr;
// ... code ...
arr = new int[size];
for (int i = 0; i < 5; i++) {
arr[i] = UN;
}
Basically, I want to declare arr once I know what its size will be and initialize it to UN without having to loop. So something like this:
int[] arr = new int[size] = UN;
Is this possible?
Thanks.
Arrays.fill(arr, UN);
You don't need to initialize them with 0. An int defaults to 0 already.
Just
int[] array = new int[size];
is enough. It gives you an array of zeroes of the given length. If it were an Integer[], it would have been an array of nulls.
Well, in the case of objects (or primitives with autoboxing) you can do the following:
int count = 20;
final int UN = 0;
Integer[] values = Collections.nCopies(count, UN).toArray(new Integer[count]);
The downsides are that you have to use the object forms of the primitives (since the Collections must be of objects) and a separate List will be constructed and then thrown away. This would allow you to create the array as one statement however.
No, not with the standard libraries. If you write your own functions, though, you can easily do so in a single statement (not instruction; those are different). Mine looks like String[][] strings = Arrayu.fill(new String[x][y], "");
Here's a link. There's some junk in there too, though; I just posted a copy of the current source directly without cleaning it up.
No.
Next question?
int arr[] = { 0, 0, 0, 0, 0 };
Oops, read your question better:
You can init an array like so
int[] arr = new int[] {UN, UN, UN, UN, UN};
But ofcourse, if you don't know the size at compile time, then you have to do the for loop. The second technique is not possible.