import java.util.function.Function;
import java.util.stream.Stream;
public class GdkStreams
{
public static <T, K, V> Function<T, Stream<FlatEntry<K, V>>> flatEntryMapper(Function<T, K> keyMapper,
Function<T, Stream<V>> valueMapper)
{
return input -> {
K key = keyMapper.apply(input);
return valueMapper.apply(input).map(value -> new FlatEntry<>(key, value));
};
}
public static <T, K, V> FlatEntryMapperBuilder<T, K, V> flatEntryMapperBuilder(Function<T, K> keyMapper,
Function<T, Stream<V>> valueMapper)
{
return new FlatEntryMapperBuilder<>(keyMapper, valueMapper);
}
public static class FlatEntryMapperBuilder<T, K, V>
{
private Function<T, K> keyMapper;
private Function<T, Stream<V>> valueMapper;
private FlatEntryMapperBuilder (Function<T, K> keyMapper, Function<T, Stream<V>> valueMapper)
{
this.keyMapper = keyMapper;
this.valueMapper = valueMapper;
}
public Function<T, Stream<FlatEntry<K, V>>> build()
{
return flatEntryMapper(keyMapper, valueMapper);
}
public <K2, V2> FlatEntryMapperBuilder<T, K, FlatEntry<K2, V2>> chain(Function<V, K2> keyMapper2,
Function<V, Stream<V2>> valueMapper2)
{
return new FlatEntryMapperBuilder<>(keyMapper,
valueMapper.andThen(stream -> stream.flatMap(flatEntryMapper(keyMapper2,
valueMapper2))));
}
}
public static class FlatEntry<K, V>
{
public final K key;
public final V value;
public FlatEntry (K key, V value)
{
this.key = key;
this.value = value;
}
}
}
Map<String, Set<String>> level1Map;
我可以通过执行以下操作将子集中的每个元素映射到一个FlatEntry:
level1Map.entrySet().stream().flatMap(GdkStreams.flatEntryMapper(Entry::getKey, entry -> entry.getValue().stream()));
而且效果很好。但当我尝试这样做时:
level1Map.entrySet()
.stream()
.flatMap(GdkStreams.flatEntryMapperBuilder(Entry::getKey, entry -> entry.getValue().stream()).build());
eclipse(Mars4.5.0)编译器的功能如下:
- The type Map.Entry does not define getKey(Object) that is applicable here
- The method getValue() is undefined for the type Object
- Type mismatch: cannot convert from GdkStreams.FlatEntryMapperBuilder<Object,Object,Object> to
<unknown>
MainTest.java:50: error: incompatible types: cannot infer type-variable(s) T,K#1,V#1
.flatMap(GdkStreams.flatEntryMapperBuilder(Entry::getKey, entry -> entry.getValue().stream()).build());
^
(argument mismatch; invalid method reference
method getKey in interface Entry<K#2,V#2> cannot be applied to given types
required: no arguments
found: Object
reason: actual and formal argument lists differ in length)
where T,K#1,V#1,K#2,V#2 are type-variables:
T extends Object declared in method <T,K#1,V#1>flatEntryMapperBuilder(Function<T,K#1>,Function<T,Stream<V#1>>)
K#1 extends Object declared in method <T,K#1,V#1>flatEntryMapperBuilder(Function<T,K#1>,Function<T,Stream<V#1>>)
V#1 extends Object declared in method <T,K#1,V#1>flatEntryMapperBuilder(Function<T,K#1>,Function<T,Stream<V#1>>)
K#2 extends Object declared in interface Entry
V#2 extends Object declared in interface Entry
MainTest.java:50: error: invalid method reference
.flatMap(GdkStreams.flatEntryMapperBuilder(Entry::getKey, entry -> entry.getValue().stream()).build());
^
non-static method getKey() cannot be referenced from a static context
where K is a type-variable:
K extends Object declared in interface Entry
2 errors
MainTest.java:51: error: cannot find symbol
.flatMap(GdkStreams.flatEntryMapperBuilder(entry -> entry.getKey(), entry -> entry.getValue().stream()).build());
^
symbol: method getKey()
location: variable entry of type Object
MainTest.java:51: error: cannot find symbol
.flatMap(GdkStreams.flatEntryMapperBuilder(entry -> entry.getKey(), entry -> entry.getValue().stream()).build());
^
symbol: method getValue()
location: variable entry of type Object
2 errors
level1Map.entrySet()
.stream()
.flatMap(GdkStreams.<Entry<String, Set<String>>, String, String> flatEntryMapperBuilder(Entry::getKey,
entry -> entry.getValue()
.stream())
.build());
Function<Entry<String, Set<String>>, String> keyGetter = Entry::getKey;
level1Map.entrySet()
.stream()
.flatMap(GdkStreams.flatEntryMapperBuilder(keyGetter, entry -> entry.getValue().stream()).build());
Map<String, Map<String, Set<String>>> level2Map;
我是不是漏掉了什么?我能纠正我的API,使它的使用不那么笨拙吗?还是我一直在指定类型参数?谢谢!
霍尔格在评论区的回答在我看来是最好的:
这是Java8的类型推断的一个已知限制:它不能与诸如genericfactorymethod().build()
之类的链接方法调用一起工作。
谢谢!关于我的API,我将在将函数用作参数之前指定它们,如下所示:
Function<Entry<String, Set<String>>, String> keyMapper = Entry::getKey;
Function<Entry<String, Set<String>>, Stream<String>> valueMapper = entry -> entry.getValue().stream();
public static <T, R> Function<? super T, Stream<FlatEntry<T, R>>> flatEntryMapper(Function<? super T, ? extends Stream<? extends R>> mapper)
{
return element -> mapper.apply(element).map(value -> new FlatEntry<>(element, value));
}
public static class FlatEntry<E, V>
{
/** The original stream element */
public final E element;
/** The flattened value */
public final V value;
private FlatEntry (E element, V value)
{
this.element = element;
this.value = value;
}
}
Map<String, Map<String, Map<String, Set<String>>>> level3Map;
// gives a stream of all the flattened values
level3Map.entrySet()
.stream()
.flatMap(entry -> entry.getValue().entrySet().stream())
.flatMap(entry -> entry.getValue().entrySet().stream())
.flatMap(entry -> entry.getValue().stream());
// gives a stream of FlatEntries with flattened values and all their original elements in nested FlatEntries
level3Map.entrySet()
.stream()
.flatMap(GdkStreams.flatEntryMapper(entry -> entry.getValue().entrySet().stream()))
.flatMap(GdkStreams.flatEntryMapper(flatEntry -> flatEntry.value.getValue().entrySet().stream()))
.flatMap(GdkStreams.flatEntryMapper(flatEntry -> flatEntry.value.getValue().stream()));
我正在寻找一种方法来调用多个参数方法,但是使用构造。文档中说只有在能够映射到功能接口时才可用。 基本上,如上所述,考虑使用中不同数量的属性的方法。
我正在从文档中学习反应,但不确定在这个例子中超级()做什么。通常,它不需要传递给创建新实例的参数,然后调用React吗?组件的构造函数方法将这些参数合并到实例中?没有任何争论它是做什么的?
我只想传递一个lambda(代码块),并在需要时执行它。如何在下面的代码中实现方法(以及方法签名是什么):
问题内容: 所以我看过很多这样的例子: 您似乎可以通过成功函数以警报的形式查看从c#方法返回的数据。但是,如果我想在函数调用之外访问此“ input + 1”数据,该怎么做呢?另外我不确定如何调用没有参数的方法? 最后,我想使用通过ajax调用的ac#方法返回的JSON数据填充下拉列表,但是我不确定如何处理似乎卡在函数中的JSON数据呼叫? 抱歉,我是Jquery / AJAX / etc的新手,
我正试图做到这一点: 然而,类型擦除似乎会去除字符串,所以当我调用时,我会返回一个原始
是否有可能将方法引用与参数一起使用?我喜欢流的想法,我只是想让代码更易读。 实际上,我认为有一个类似的问题,方法引用了一个参数,我读了,但不知道如何在我的代码中使用bind2方法。这是唯一的解决办法吗?