How can I map over an array in Java?

Ashton Wiersdorf :

I have an array of Strings

String[] suffixes = getSuffixes();

and I want a new array based on the old one with a prefix appended. I'd do something like this in Ruby, JavaScript, Perl, Lisp, and the like:

// pseudocode for what I would like

String[] full_words = suffixes.map(suffix => "re" + suffix);

I'm limited to Arrays in my application. (This is a small part of an assignment for school and I'm not allowed to use the Collections library.) Any way to do this in Java 8?

khachik :
String [] full_suffixes = Arrays.stream(suffixes)
                          .map(suffix -> "re" + suffix)
                          .toArray(size -> new String[size])

"ol' fashioned" loop is too verbose:

String [] full_suffixes = new String[suffixes.length];
for(int i = 0; i < suffixes.length; i++) {
    full_suffixes[i] = "re" + suffixes[i];
}

To address the "much too fast" comment:

import java.util.Arrays;

public class Test {
    static int N = 10000;
    public static void main(String [] args) throws Exception {
        if(args.length > 0) {
            N = Integer.parseInt(args[0]);
        }
        String [] array = new String[100000];
        for(int i = 0; i < array.length; i++) {
            array[i] = "abcdef" + i;
        }
        long start = System.currentTimeMillis();
        fancy(array);
        System.err.println("Fancy took " + (System.currentTimeMillis() - start) + "ms");
        start = System.currentTimeMillis();
        oldSchool(array);
        System.err.println("Loop took " + (System.currentTimeMillis() - start) + "ms");

    }

    public static void fancy(String [] array) {
        for(int i = 0; i < N; i++) {
            String [] full_suffixes = Arrays.stream(array)
                                          .map(suffix -> "re" + suffix)
                                          .toArray(size -> new String[size]);
        }
    }

    public static void oldSchool(String [] array) {
        for(int i = 0; i < N; i++) {
            String [] full_suffixes = new String[array.length];
            for(int j = 0; j < array.length; j++) {
                    full_suffixes[j] = "re" + array[j];
            }
        }
    }
}

Running (jdk 1.8.0_60):

$ java Test 100
Fancy took 502ms
Loop took 398ms
$ java Test 1000
Fancy took 3067ms
Loop took 2227ms
$ java Test 5000
Fancy took 13288ms
Loop took 11494ms
$ java Test 10000
Fancy took 27744ms
Loop took 27446ms

I would not call this much faster, but yeah, unfortunately there is a trade-off between performance and code clarity in the current implementation of streaming framework.

Edit: To address the discussion about map vs for loops - it is not about hte number of lines or characters to type, maybe I'm also spoilt by languages with higher-order functions, but for me there is a mental disconnect between transforming a collection (which is simply what map does) and putting my brain into the details of its size and how to get/assign elements. Also it is worth to mention that Java streaming framework is still ages behind.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=81377&siteId=1