[英]Java 8- Lambda expression and streams to iterate over HashMap of HashMap
I need to iterate over HashMap of HashMap using lambda expressions and filter out few undesired entries. 我需要使用lambda表达式迭代HashMap的HashMap,并过滤掉一些不需要的条目。 I tried a few approaches but it doesn't seem to work.
我尝试了几种方法,但似乎没有用。 Below is the structure of the map.
以下是地图的结构。
Map<String, Map<Date, String>> sensor_tags = new HashMap<String, Map<Date,String>>();
From this map, I need to remove the entries where sensor data is older than certain date (date is key of inner map). 从此地图中,我需要删除传感器数据早于特定日期的条目(日期是内部地图的键)。 Below is the sample data for the map sensor_tags-
以下是地图sensor_tags-的示例数据
String tagName = "zoneSensor";
Map<Date, String> values= new HashMap<Date, String>();
// (1st entry for tag 1) --> date is day before yesterday
Calendar datekey1 = Calendar.getInstance();
datekey1.set(2018, 12, 01, 12, 30, 45);
values.put(datekey1.getTime(), "ON");
// (2nd entry for tag 1) --> date is yesterdys date
Calendar datekey = Calendar.getInstance();
datekey.set(2018, 12, 02, 12, 30, 45);
values.put(datekey.getTime(), "OFF");
// (3rd entry for tag 1) --> date is today
Calendar instance = Calendar.getInstance();
instance.set(2018, 12, 03, 12, 30, 45);
values.put(instance.getTime(), "ON");
//(4th entry for tag 1)--> date is today + 10 sec
instance.add(Calendar.MILLISECOND, 10000);
sensor_tags.put(tagName, values);
values.put(instance.getTime(), "ON");
sensor_tags.put(tagName, values);
// 5th entry for tag2
tagName = "zoneSensor1";
values= new HashMap<Date, String>();
values.put(Calendar.getInstance().getTime(), "NORMAL");
sensor_tags.put(tagName, values);
//code in java 7
for (final Entry<String, Map<Date, String>> entry : sensor_tags.entrySet()) {
final Iterator<Date> iter = entry.getValue().keySet().iterator();
while (iter.hasNext()) {
final Date date = iter.next();
if (date.before(givendate)) {
iter.remove();
}
}
}
// code tried in java 8 (I am a beginner here :-) )
sensor_tags
.entrySet()
.stream()
.map(Map.Entry::getValue) // get an inner map
.filter(value -> ((Date)value).before(datekey.getTime()));
How can I iterate over and filter data for inner maps? 如何遍历和过滤内部地图的数据? Also, once the data is filtered, I need to retain structure of the map as is, hence the output needs to be collected in
Map<String, Map<Date, String>>
only. 同样,一旦数据被过滤,我就需要保持地图的结构不变,因此仅需要在
Map<String, Map<Date, String>>
收集输出。
If you want to modify the existing map, you don't need streams. 如果要修改现有地图,则不需要流。 Just loop and call
removeIf()
: 只需循环并调用
removeIf()
:
sensor_tags.values().forEach(
m -> m.keySet().removeIf(datekey.getTime()::after));
if you don't want to modify the existing map then there's no need for a stream, you could simplify your imperative approach to: 如果您不想修改现有地图,则不需要流,则可以简化命令式方法以:
for (final Map<Date, String> v : sensor_tags.values()) {
v.keySet().removeIf(d -> d.before(datekey.getTime()));
}
if you don't want to modify the existing map then you can do: 如果您不想修改现有地图,则可以执行以下操作:
Map<String, Map<Date, String>> result = sensor_tags.entrySet()
.stream()
.collect(toMap(
Map.Entry::getKey,
e -> e.getValue().entrySet().stream()
.filter(a -> !a.getKey().before(datekey.getTime()))
.collect(toMap(Map.Entry::getKey,
Map.Entry::getValue))));
I have made these two methods for you. 我为您制作了这两种方法。 The first creates a new hashmap and the second changes your Hashmap on the fly with the desired filtering.
第一个创建新的哈希图,第二个使用所需的过滤动态更改您的Hashmap。 I didn't check for corner cases but they seem to work.
我没有检查极端情况,但它们似乎有效。 Hope this helps:
希望这可以帮助:
Keeps your hashmap 保留您的哈希图
private Map<String, Map<Date, String>> getFilteredResultsKeeping(Map<String, Map<Date, String>> sensor_tags,
Date givendate) {
return sensor_tags.entrySet().stream()
.map(sensorValue -> new SimpleEntry<>(sensorValue.getKey(),
sensorValue.getValue().entrySet().stream()
.filter(sensor -> !sensor.getKey().before(givendate))
.map(sensor -> sensor.getKey())
.collect(toMap(date -> date, date -> sensorValue.getValue().get(date)))))
.collect((toMap(SimpleEntry::getKey, SimpleEntry::getValue)));
}
Changes your hashmap 更改您的哈希图
private Map<String, Map<Date, String>> getFilteredResultsRemoving(Map<String, Map<Date, String>> sensor_tags,
Date givendate) {
return sensor_tags.entrySet().stream()
.peek(sensorValue -> {
List<Date> invalidDates = sensorValue.getValue().entrySet().stream()
.map(sensor -> sensor.getKey())
.filter(date -> date.before(givendate)).collect(Collectors.toList());
invalidDates.forEach(date -> sensorValue.getValue().remove(date));
})
.collect((toMap(Entry::getKey, Entry::getValue)));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.