是否有可能以某种方式参数化Java 8 Consumer?我希望有可重复使用的消费者,我可以在其中使用其他参数。
List<DateTime> dates = new ArrayList<DateTime>();
Set<Alarm> alarms = new HashSet<Alarm>();
Consumer<Entry> entryConsumer1 = entry -> {
LocalTime time = entry.getDate().toLocalTime();
Alarm alarm = new Alarm(time, calendar1.getPattern());
alarms.add(alarm);
dates.add(entry.getDate());
};
Consumer<Entry> entryConsumer2 = entry -> {
LocalTime time = entry.getDate().toLocalTime();
Alarm alarm = new Alarm(time, calendar2.getPattern());
alarms.add(alarm);
dates.add(entry.getDate());
};
calendar1.generateEntries(criteria).forEach(entryConsumer1);
calendar2.generateEntries(criteria).forEach(entryConsumer2);
calendar1,calendar2是同一类型
正如您所看到的,两个消费者只有一个参数不同。是否可以简化此代码/不重复?
答案 0 :(得分:4)
为您的消费者创建工厂方法:
public Consumer<Entry> createConsumer(Calendar calendar, Set<Alarm> alarms, List<DateTime> dates) {
return entry -> {
LocalTime time = entry.getDate().toLocalTime();
Alarm alarm = new Alarm(time, calendar.getPattern());
alarms.add(alarm);
dates.add(entry.getDate());
}
}
然后像这样使用它:
calendar1.generateEntries(criteria).forEach(createConsumer(calendar1, alarms, dates));
calendar2.generateEntries(criteria).forEach(createConsumer(calendar2, alarms, dates));
但是:对于具有副作用的lambda表达式或函数,例如向警报集添加警报或将日期添加到lambda内的日期列表,这是不好的做法(针对函数式编程原则)。更实用的方法是使用map
等转换方法,然后收集结果。例如:
Set<Alarm> alarms = calendar1.generateEntries(criteria)
.map(entry -> new Alarm(entry.getDate().toLocalTime(), calendar1.getPattern()))
.collect(Collectors.toSet());
答案 1 :(得分:2)
我们所做的是更改API,虽然这不是一个简单的选项。
BiConsumer<String, Entry> entryConsumer = (pattern, entry) -> {
LocalTime time = entry.getDate().toLocalTime();
Alarm alarm = new Alarm(time, pattern);
alarms.add(alarm);
dates.add(entry.getDate());
};
并像这样调用API(其中第一个参数传递给每次调用entryConsumer)
.forEach(calendar1.getPattern, entryConsumer);
但是,假设您无法更改API,您可以使用这样的方法。
calendar1.generateEntries(criteria).forEach(e -> entryConsumer(calendar1, e));
calendar2.generateEntries(criteria).forEach(e -> entryConsumer(calendar2, e));
public static void entryConsumer(Calendar cal, Entry e) {
LocalTime time = entry.getDate().toLocalTime();
Alarm alarm = new Alarm(time, cal.getPattern());
alarms.add(alarm);
dates.add(entry.getDate());
};