我刚开始看Java 8并试用lambdas,下面是我想要解决的问题
以下是我到目前为止的代码
type P1 P2 P3 P4 device_ts
COV 2969 2017-04-30 21:54:59
COV 2967 2017-04-30 21:56:16
INT 2967 2297 2017-04-30 22:00:00
COV 2965 2017-04-30 22:08:00
INT 2966 2301 2017-04-30 22:15:01
INT 2963 2299 2017-04-30 22:30:03
COV 2961 2017-04-30 22:35:00
COV 2963 2017-04-30 22:43:40
上面的代码片段有效,但那不是我想要的。我希望它返回while($data = $P1->fetch(PDO::FETCH_ASSOC))
{
if($data['type']=="INT")
{
echo "<tr>";
echo "<td>P1 value is : ".$data['P1']."</td>";
echo "<td>P2 value is : ".$data['P2']."</td>";
echo "<td>P3 value is : ".$data['P3']."</td>";
echo "<td>P4 value is : ".$data['P4']."</td>";
echo "<td>Time stamp. : ".$data['device_ts']."</td>";
echo "</tr>";
}
}
我猜测平面映射的某种方式将解决问题
OperatorType枚举以供参考
Map<String, List<List<DataType>>> a = Arrays.stream(OperatorType.values())
.collect(
groupingBy(i -> i.getKey(),
mapping(i -> i.getSupportedtypes(),
Collectors.toList())));
}
找到一种方法:
Map<String, List<DataType>>
答案 0 :(得分:2)
我已经抛出了一些方法,并在你的枚举中用DataType
切换了Integer
,它现在看起来像这样:
enum OperatorType {
IS_ONE_OF("IS_ONE_OF", 1,
Collections.singletonList(1)),
IS_NOT_ONE_OF("IS_NOT_ONE_OF", 2,
Collections.singletonList(1)),
ENDS_WITH("ENDS_WITH", 3,
Collections.singletonList(2)),
DOES_NOT_ENDS_WITH("DOES_NOT_ENDS_WITH", 4,
Collections.singletonList(2)),
STARTS_WITH("STARTS_WITH", 5,
Collections.singletonList(2)),
DOES_NOT_START_WITH("DOES_NOT_START_WITH", 6,
Collections.singletonList(2)),
MATCHES("MATCHES", 7,
Collections.singletonList(2)),
DOES_NOT_MATCH("DOES_NOT_MATCH", 8,
Collections.singletonList(2)),
CONTAINS("CONTAINS", 9,
Collections.singletonList(2)),
DOES_NOT_CONTAIN("DOES_NOT_CONTAIN", 10,
Collections.singletonList(2)),
GREATER_THAN("GREATER_THAN", 11, Arrays.asList(3,4)),
GREATER_THAN_OR_EQUAL_TO("GREATER_THAN_OR_EQUAL_TO", 12, Arrays.asList(3,4)),
LESS_THAN("LESS_THAN", 13, Arrays.asList(3,4)),
LESS_THAN_OR_EQUAL_TO("LESS_THAN_OR_EQUAL_TO", 15, Arrays.asList(3,4)),
AFTER("AFTER", 15,
Collections.singletonList(5)),
BEFORE("BEFORE", 16,
Collections.singletonList(5));
private final int value;
private final String key;
private final List<Integer> supportedtypes;
OperatorType(String key, int value, List<Integer> supportedtypes) {
this.value = value;
this.key = key;
this.supportedtypes = supportedtypes;
}
public int getValue() {
return this.value;
}
public String getKey() {
return this.key;
}
public List<Integer> getSupportedtypes() {
return this.supportedtypes;
}
@Override
public String toString() {
return String.valueOf(this.value);
}
}
将DataType
切换回以下代码应该非常简单:
Map<String,List<Integer>> map = Arrays.stream(OperatorType.values()).collect(Collectors.toMap(OperatorType::getKey, OperatorType::getSupportedtypes));
map.forEach((k,v) -> System.out.println(k + " " + v));
System.out.println("");
Map<Integer,List<OperatorType>> map2 =
map.entrySet().stream()
.flatMap(e -> e.getValue().stream().map(f -> new AbstractMap.SimpleEntry<>(f,e.getKey())))
.collect(Collectors.groupingBy(r -> r.getKey(), Collectors.mapping(s -> Enum.valueOf(OperatorType.class, s.getValue()), Collectors.toList())));
map2.forEach((k,v) -> System.out.println(k + " " + v));
您可以将这两个步骤链接起来。但为了便于阅读,我将它们分开了。
对我来说,print语句打印如下:
DOES_NOT_CONTAIN [2]
STARTS_WITH [2]
LESS_THAN_OR_EQUAL_TO [3, 4]
DOES_NOT_MATCH [2]
AFTER [5]
DOES_NOT_ENDS_WITH [2]
IS_ONE_OF [1]
LESS_THAN [3, 4]
GREATER_THAN_OR_EQUAL_TO [3, 4]
CONTAINS [2]
DOES_NOT_START_WITH [2]
IS_NOT_ONE_OF [1]
BEFORE [5]
GREATER_THAN [3, 4]
ENDS_WITH [2]
MATCHES [2]
1 [2, 1]
2 [7, 3, 6, 9, 4, 8, 5, 10]
3 [11, 12, 13, 15]
4 [11, 12, 13, 15]
5 [16, 15]
我知道这个答案缺少一些解释,但它产生了你想要的Map<DataType,List<OperatorType>>
答案 1 :(得分:1)
看起来您的密钥与枚举名称相同。如果是这样的话:
a)你根本不需要钥匙;只需使用枚举常量的名称:
public String getKey() {
return this.name();
}
b)由于密钥是唯一的,因此不需要分组。请改用toMap()
收集器:
Map<String, List<DataType>> a = Arrays.stream(OperatorType.values())
.collect(toMap(OperatorType::getKey, OperatorType::getSupportedtypes));
答案 2 :(得分:0)
您应该可以使用Stream#flatMap
:
Map<String, List<DataType>> map = new HashMap<>();
a.entrySet().forEach(entry -> {
map.put(entry.getKey(), entry.getValue().stream()
.flatMap(List::stream)
.collect(Collectors.toList()));
});
由于List
的每个值中List
的{{1}}必须缩小,我们必须首先制作一个新的Map
,然后重新添加元素凝聚每个Map
答案 3 :(得分:0)
一种方法是将收藏家toList
替换为更合适的收藏家,例如reducing
:
Map<String, List<DataType>> a = Arrays.stream(OperatorType.values())
.collect(
groupingBy(i -> i.getKey(),
mapping(i1 -> i1.getSupportedtypes(),
reducing((List<DataType>) new ArrayList<DataType>(), (l,r) -> {
List<DataType> list = new ArrayList<DataType>();
list.addAll(l);
list.addAll(r);
return list;
}))));
为了更好的可读性,提取二元运算符函数可能会有所帮助,例如: (l,r) -> join(l,r)
,其中join
连接两个列表。