0

I'm just barely learning Java and need to accomplish something in Java 8, but I'm struggling to figure out the most efficient way to do it (coming from a PHP background). Essentially I'm trying to give it a regular array, run some calculations, and then save some of those values in a new array where the original key is preserved.

So basically the original array is something like:

0 => 3 1 => 5 2 => 6 3 => 8 

and the new array will be an associative array where the keys are specifically assigned like:

1 => 5 3 => 8 

In order to help myself visualize it in something I'm more familiar with, I've gotten everything I need working in PHP, and it looks something like this:

$array = array( 8, 3, 2, 9, 1, 15 ); $new_array = array(); foreach ( $array as $key => $value ) { // Calculate something and build new array, for example... if ( 5 > $value ) { $new_value = $value + 5; $new_array[ $key ] = $new_value; } } 

So in this example, $new_array would be:

1 => 8 2 => 7 4 => 6 

I would swear I've seen something where I can do just a basic for loop and access key and value but I can't find where I read that, and everything else I'm finding now talks about iterating through "hash maps" using forEach(), so that seems like the standard approach, but when I try array.forEach((k, v) -> // Calculations.... it tells me that it "cannot find symbol" for array in that context, which is being set immediately prior as int[] array = { // numbers }. As I'm understanding it, I have to convert the array to a hash map in order to be able to use a key/value pair in the foreach, but apparently I'm doing something wrong there as well...

So I guess here are my questions...

  1. Can I use a basic for loop for this or I need to convert the array to a hash map in order to access the key/value pairs? How? I don't need to use any specific method, just looking for the most efficient.
  2. I have import java.util.Arrays; for other reasons - do I need to import something else?

Thanks for your help.

UPDATE -------------------------

To clarify, I'll need to do something similar later in the code again using $new_array as the source, so I need to be able to get the keys and not just the iteration count.

So for example if I were to wrap the foreach in a while loop, where the first time it starts with $array and each subsequent time it sets $array as $new_array to run the calculations again.

So in other words, I can't rely on the iteration count to match the keys.

6
  • Use a basic for loop and store the result in a Map using the index variable as the key. Commented Nov 28, 2020 at 12:29
  • @JoakimDanielson Later in the code I'll need to do something similar with the $new_array though, so the counter won't match the keys. Is there a way to specifically get the key value? Commented Nov 28, 2020 at 12:32
  • Not sure what you mean but notice that the variable you call $new_array is a Map in java. It should probably work the same in java as in php Commented Nov 28, 2020 at 12:35
  • Sorry - I'll add an update to the question and see if I can explain. Commented Nov 28, 2020 at 12:37
  • I still don’t understand, you will have the keys if you use a Map. And if you want to use a for each loop instead then why not manually keep track of the index with a variable. Or use a Map instead of an array to start with Commented Nov 28, 2020 at 12:44

2 Answers 2

2

It is possible to use Stream API to convert array into map in a functional way:

  • use IntStream.range to create a stream of integers
  • collected into map using Collectors.toMap:

For a new map, filter operation can be applied to select values less than 5.

// these imports to be added import java.util.*; import java.util.stream.*; int [] array = {8, 3, 2, 9, 1, 15}; Map<Integer, Integer> map = IntStream.range(0, array.length) // stream of int indexes .boxed() // stream of Integer .collect(Collectors.toMap( i -> i, // use index as key i -> array[i] // get array element as value )); Map<Integer, Integer> mapNew = IntStream.range(0, array.length) .boxed() .filter(i -> array[i] < 5) .collect(Collectors.toMap(i -> i, i -> array[i] + 5)); System.out.println("old map:" + map); // printing each entry in new map using lambda mapNew.forEach((k, v) -> System.out.println(k + " -> " + v)); // use common for loop by entries System.out.println("----"); for(Map.Entry<Integer, Integer> entry : mapNew.entrySet()) { System.out.println(entry.getKey() + " => " + entry.getValue()); } 

Output:

old map:{0=8, 1=3, 2=2, 3=9, 4=1, 5=15} 1 -> 8 2 -> 7 4 -> 6 ---- 1 => 8 2 => 7 4 => 6 
Sign up to request clarification or add additional context in comments.

6 Comments

Trying this out - I'm getting a 'cannot find symbol' on Map. Do I need to import something?
yes, sure, I updated the answer. These imports needed: import java.util.*; to get Map and import java.util.stream.*; to get IntStream, Collectors
This may be a different question but is there a way to set up the foreach not as a lambda so I can use local variables inside it (that were set outside of it)?
Sure, foreach loop for map iterate over map.entrySet()
Amazing, thanks! Last question - the array is small but if it gets quite large - say 10,000 - do you know if there would be any performance issues from calling something like getKey() or it that pretty fast?
|
1

You can use a regular for loop:

int [] array = {8, 3, 2, 9, 1, 15}; Map<Integer, Integer> map = new HashMap<>(); // Print the results for (int i = 0; i < array.length; i++) { if (5 > array[i]) { map.put(i, array[i] + 5); } } for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + "=>" + entry.getValue()); } 

6 Comments

Thanks! Sorry I updated my question - I have to get the actual keys as they may not match the iteration count. Is there a way to modify this to do that?
@Shoelaced If there are keys then it is not an array. The source data is in a map?
The initial $array is just a regular array, but it sounds like $new_array output will be a map, and since I'll need to run the same foreach again on $new_array, it sounds like I need to first convert $array to a map and go from there?
Yes, I guess that is what you need to do. Arrays and maps are (obviously) very different and are accessed using different semantics so the same loop won't work on both.
I see... how would I convert the array to a map? I can search around but if you can update your answer that'd be helpful too.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.