#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