В любом случае есть ли в java.1.8 передавать / хранить ссылки на функции на карте, как в Scala? - PullRequest
1 голос
/ 19 апреля 2019

Я пытаюсь преобразовать предыдущий код scala в код java 1.8.

В scala я использовал Map для хранения всех соответствующих ссылок на функции классов.Как показано здесь в классе Driver.scala функция getAllDefinedProcessors () класса.

https://gist.github.com/shatestest/86ae9559c6114999e13a6eec3c80ec2b

object Driver {

 ...

  def main(args: Array[String]): Unit = {

   val procs :  LinkedHashMap[String, (DataFrameReader, SparkSession, String) => Unit] = getAllDefinedProcessors();


       for ( key <- procs.keys){
            procs.get(key).map{
                println("process started for loading column family : " + key);
               fun => fun(ora_df_options_conf,spark,columnFamilyName)
         }
        }

     }

     def getAllDefinedProcessors(): LinkedHashMap[String, (DataFrameReader, SparkSession, String) => Unit] = {
         LinkedHashMap(
          "bm_vals" -> new BMValsProcessor().process,
          "bm_vals2" -> new BMValsProcessor2().process
        )
     }
}

Как преобразовать эти эквивалентные функциональные возможности Java 1.8?Поддерживает ли Java 1.8 функциональные ссылки?Если так, как продолжить?Любой альтернативный способ для того же?

Спасибо.

1 Ответ

2 голосов
/ 19 апреля 2019

Я не совсем уверен, что понимаю ваш вопрос, но вот попытка найти решение.Функциональные возможности Java существуют, но на самом деле они представляют собой простые интерфейсы, и для их создания безболезненно существует специальный синтаксис.К сожалению, я не думаю, что в вашем конкретном сценарии есть предопределенный класс функций, но есть два, плюс способ сгенерировать тот, который вам не хватает:

import java.util.function.Function;
import java.util.function.Consumer;

public class Junk {
  public static void main(String[] args) {
    Function<Integer, Integer> square = x -> x * x;  // This is basically your lambda function
    System.out.println("This should print 9: " + square.apply(3));

    Consumer<String> prefixedText = text -> System.out.println("This is crazy, but " + text); // there's nothing special about the variable naming

    prefixedText.accept("it actually works!");
    // Per java, there are a few types of lambdas. Here are 3 that come to mind -- they're all under java.util.function
    // Function (also BiFunction, which takes 2 arguments) -- takes an argument, produces a result
    // Consumer (also BiConsumer) -- takes an argument, but produces nothing
    // Supplier -- takes no arguments, and produces  something

    // The abstractions they have only defined for a particular subset of function types though. it looks like you need a TriConsumer...
    TriConsumer<Integer, Integer, Integer> iDunno = (a, b, c) -> System.out.println("I can't think of an example of a tri consumer. But you get the idea. " + a + b + c);
    iDunno.accept(1, 2, 3);
  }

  interface TriConsumer<T,U,V> implements {
    public abstract void accept(T one, U two, V three);
  }
}

Если вы хотите разместить этив карту, очевидно, им всем нужно было бы использовать один и тот же тип / универсальный тип, но затем вы могли бы создать хэш-карту, чтобы хранить их все:

HashMap<String, TriConsumer> someMap = new HashMap<>();
someMap.put("key1", (a,b,c) -> System.out.println());
someMap.put("key2", (a,b,c) -> /*etc*/);

Одна вещь, которую нужно иметь в виду - эти функции могутнет исключенийЕсли вы хотите иметь исключения, вам нужно вставить их в интерфейс - например, interface MyFunction<T, U>{ public U apply(T t) throws IOException{} }, если вы хотели / хотели иметь возможность генерировать исключения в вашей лямбда-функции при выполнении некоторой обработки io.

Еще одно примечание: возвращение неявно для одной командной функции.Если вам нужна более длинная функция, вы можете обернуть ее в {} как обычно, но тогда вам нужно сделать явный возврат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...