4

I'm used to declaring array inline like this:

    String s1 = "world";
    String[] strings = { "world" };

Why can't I do the same for functions? Given I have a class Book with getTitle() and getAuthor() methods, this is valid:

    Function<Book, String> f1 = Book::getTitle;
    System.out.println(f1.apply(myBook));

However this is not:

    Function<Book, String>[] funcs = { Book::getTitle, Book::getAuthor };
    for (Function<Book, String> f2 : funcs) {
        System.out.println(f2.apply(myBook));
    }

It doesn't like the inline array declaration and the compiler error is "Cannot create a generic array of Function"

Edit I'd argue my question isn't a duplicate of the suggestion as I want to statically define a set of functions using the array initializer syntax

batwad
  • 3,588
  • 1
  • 24
  • 38
  • Try with a map, like this `Map> mapToFunctions = new HashMap<>();` – Victor M Perez Jan 29 '18 at 15:49
  • If is a generic type, you need to use `funcs = new Function[] { Book::getTitle };` – Héctor Jan 29 '18 at 15:51
  • @Héctor that gives the same error – batwad Jan 29 '18 at 16:02
  • `Function[] funcs = { (Function) Book::getTitle };`. – Ole V.V. Jan 29 '18 at 16:16
  • If you want to simply apply the same method call to all of your books(assuming books is a List), you can simply do `List titles = books.stream().map(Book::getTitle).collect(Collectors.toList());` and then `titles.stream().forEach(System.out::println);` to print them. It is redundant to create an array of the same function. – ichantz Jan 29 '18 at 19:26
  • @ichantz my example is greatly simplified; in reality I want to statically define many functions in an array or list and invoke them in turn on multiple instances – batwad Jan 30 '18 at 09:43

1 Answers1

2

You could try this:

public static void testFunction() {
    Map<String, Function<Book, String>> mapToFunctions = new HashMap<>();

    Function<Book, String> myFunction = x -> new String(x.getTitle());

    mapToFunctions.put("firstfunction", myFunction);

    for (Function<Book, String> f : mapToFunctions.values()) {
        System.out.println(f.apply(new Book("my title")));
    }
}

UPDATE:

Using Set<Function<Book, String>> it would be something like:

package com.victor.main;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;

public class FunctionalTest {
    public static void testFunction() {
        Set<Function<Book, String>> mapToFunctions = new HashSet<>();

        Function<Book, String> myFunction = x -> new String(x.getTitle());

        mapToFunctions.add(myFunction);

        for (Function<Book, String> f : mapToFunctions) {
            System.out.println(f.apply(new Book("my title")));
        }
    }

    public static void main(String[] args) {
        testFunction();
    }
}
Victor M Perez
  • 2,185
  • 3
  • 19
  • 22