Как запустить лямбда-выражение, которое является значением на карте

#java #lambda #maps

#java #лямбда #Карты

Вопрос:

Я совсем новичок в Java, и я пытаюсь создать набор объектов, которые получены с помощью лямбда-выражений на карте. По сути, я получаю значение из карты (лямбда-выражение) и запускаю его, чтобы получить логическое значение. Однако я получаю сообщение об ошибке при запуске .apply для выражения. Есть идеи о том, как это исправить? Любая помощь приветствуется.

         Map<String, Predicate<IndexSub>> order_function = new HashMap<>();
        order_function.put("AlternativesValues", x -> false);
        order_function.put("AlternativesConstituent", x -> x.getCloseCons());
        order_function.put("EquityValues", x -> false);
        order_function.put("EquityCloseConstituent", x -> x.getCloseCons());
        order_function.put("EquityOpenConstituent", x -> x.getOpenCons());
        order_function.put("FixedValues", x -> false);
        order_function.put("FixedReturns", x -> x.getCloseCons());
        order_function.put("FixedStatistics", x -> x.getOpenCons());

        //getCloseCons and getOpenCons return true/false    

        Set<String> orderable_sub = new HashSet<String>();

        for (IndexSub s : tenant_subscriptions) {
                                 //DataProduct is a string
            if (order_function.get(DataProduct).apply(s) == true){
                orderable_sub.add(s.getIndexId());
            }

        }
  

Комментарии:

1. Что такое tenant_subscriptions?

2. В чем именно заключается ошибка? если DataProduct это целое число, вы должны разобрать его в строку, поскольку ваша карта имеет строковые ключи.

3. Что такое DataProduct ?

4. Вы получаете исключение NullPointerException, потому order_function.get(DataProduct) что возвращает null . Вы должны либо ввести в него правильные целочисленные значения в качестве ключей, либо извлечь с правильной строкой.

5. Примечание: if(boolean_condition == true) может быть сокращено до if(boolean_condition) . И еще один: DataProduct кажется, это параметр или переменная. В этом случае ему следует присвоить имя dataProduct , чтобы не путать его с именем класса (см. Соглашения о коде Java для получения дополнительной информации).

Ответ №1:

Predicate функциональный интерфейс имеет test() метод, а не apply() :

 if (order_function.get(DataProduct).test(s)){
    orderable_sub.add(s.getIndexId());
}
  

Ответ №2:

Поскольку вы, похоже, применяете один и тот же предикат ко всем элементам, tenant_subscriptions вы можете использовать поток:

 Predicate<IndexSub> p = order_function.get(dataProduct);

if( p == null ) {
  //handle that case, e.g. set a default predicate or skip the following part
}

//this assumes tenant_subscriptions is a collection, if it is an array use Arrays.stream(...) or Stream.of(...)
Set<String> orderable_sub = tenant_subscriptions.stream() //create the stream
                               .filter(p) //apply the predicate
                               .map(IndexSub::getIndexId) //map all matching elements to their id
                               .collect(Collectors.toSet()); //collect the ids into a set