我有一个以下类型的HashMap:HashMap<LocalDate, ArrayList<String>>
包含如下值:
2015-12-26=[John, J.Fox , Barry]
2015-12-24=[Barry, Michael, Martin],
2015-12-20=[McAllister, Barry, Clark]
..............
现在,如果我想在"Barry"
中搜索HashMap
并获取最新的密钥(在这种情况下是12月26日),我将如何进行此操作?
.values()
方法似乎不起作用,因为每个键都有一个ArrayList
而不是一个元素。
答案 0 :(得分:3)
在java 8中,您可以使用以下内容:
Optional<Map.Entry<LocalDate, List<String>>> first = map
.entrySet()
.stream()
.filter(entry -> entry.getValue().contains("Barry"))
.sorted(Map.Entry.comparingByKey())
.findFirst();
这将获取地图中的所有条目,根据值过滤它们,根据键对它们进行排序并获取第一个条目(如果有)。然后,您可以使用first.ifPresent()
方法对第一个条目执行任何操作,此处我只是将它们打印到控制台:
first.ifPresent(entry -> {
System.out.println(entry);
});
也许这是 NOT 最有效的算法,但确定无误
更新1:要对最新到最早的日期进行排序,请使用以下命令:
sorted(Map.Entry.<LocalDate, List<String>>comparingByKey().reversed())
更新2:正如安德烈亚斯所说,您可以使用max
代替sorted
,而Optional<Map.Entry<LocalDate, List<String>>> found = map
.entrySet()
.stream()
.filter(entry -> entry.getValue().contains("Barry"))
.max(Map.Entry.comparingByKey());
具有更好的渐近行为。事实上,由于您只需要最新的项目,因此无需对条目进行排序以获取它:
struct Header {
char tag[3];
char ver;
char rev;
char flags;
uint8_t hSize[4];
};
struct ContentFrame
{
char id[4];
uint32_t contentSize;
char flags[2];
};
int ID3_sync_safe_to_int(uint8_t* sync_safe)
{
uint32_t byte0 = sync_safe[0];
uint32_t byte1 = sync_safe[1];
uint32_t byte2 = sync_safe[2];
uint32_t byte3 = sync_safe[3];
return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;
}
const int FRAMESIZE = 10;
答案 1 :(得分:2)
使用地图的Entry Set
。例如:
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
list1.add("One");
list1.add("Two");
list1.add("Three");
list2.add("Cat");
list2.add("Dog");
list2.add("Fish");
map.put("Numbers", list1);
map.put("Animals", list2);
for(Map.Entry<String, ArrayList<String>> entry : map.entrySet())
{
if(entry.getValue().contains("Cat"))
System.out.println("Found Cat in "+entry.getKey());
}
输出:Found Cat in Animals
基本上,我们正在做的是迭代在地图的Entry Set
上,检查每个value
(我们指定的是ArrayList<String>
)是否包含{ {1}}我们正在寻找,如果是,我们会打印出当前String
的{{1}}。 (在您的情况下,这将是您的key
。)
答案 2 :(得分:1)
由于您希望在搜索值时找到密钥,因此需要使用entrySet()
。
鉴于您的密钥是日期,因此具有自然顺序,并且您想要最新的匹配日期,您有3种选择:
HashMap
,搜索整个列表,并记住最大的键值。TreeMap
,使用descendingMap()
向后搜索,然后在第一次点击时停止。TreeMap
,搜索并在首次点击时停止。如果您的列表很大和/或您进行了大量搜索,出于性能原因,最好使用TreeMap
。
由于不清楚LocalDate
是来自Java 8还是来自Joda-Time,因此以下代码使用compareTo
,它由两者实现。代码不使用Java 8特定功能。
以下是3个版本:
// HashMap
HashMap<LocalDate, ArrayList<String>> map = new HashMap<>();
...
LocalDate matchedKey = null;
for (Entry<LocalDate, ArrayList<String>> entry : map.entrySet())
if (entry.getValue().contains(valueToFind))
if (matchedKey == null || entry.getKey().compareTo(matchedKey) > 0)
matchedKey = entry.getKey();
// TreeMap (descending search)
TreeMap<LocalDate, ArrayList<String>> map = new TreeMap<>();
...
LocalDate matchedKey = null;
for (Entry<LocalDate, ArrayList<String>> entry : map.descendingMap().entrySet())
if (entry.getValue().contains(valueToFind)) {
matchedKey = entry.getKey();
break;
}
// TreeMap (reverse-order)
TreeMap<LocalDate, ArrayList<String>> map = new TreeMap<>(Collections.reverseOrder()); // or Comparator.reverseOrder() in Java 8
...
LocalDate matchedKey = null;
for (Entry<LocalDate, ArrayList<String>> entry : map.entrySet())
if (entry.getValue().contains(valueToFind)) {
matchedKey = entry.getKey();
break;
}
当然,在Java 8中,这些也可以使用流和Lambdas来完成。