如何转换Map映射<长 ,字符串>? (选项:使用番石榴)长>
我有一个 Map
String
键只不过是数字值,如“123”等。我正在获取数字值,因为这些值来自我的 JSF 组件中的 UI。我不想改变 UI 组件的契约。
现在我想基于上面的Map
创建一个Map
,我在中看到了一些
类,但都专注于转换值而不是键。transform
方法Maps
有没有更好的方法将 Map
转换为 Map
?
I have a Map<String, String>
the String
key is nothing but numeric value like "123" etc. I'm getting numeric value because this values are coming from the UI in my JSF component. I don't want to change the contract of UI component.
Now I would like to create a Map<Long, String>
based on the above Map
, I saw some transform
methods in the Maps
class but all are focusing on the converting value and not key.
Is there any better way to convert Map<String, String>
to Map<Long, String>
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
@Vivin 的答案是正确的,但我认为解释为什么 Guava 没有任何方法允许您转换
Map
的键(或转换Set
> 根本)。Guava 的所有转换和过滤方法都会产生惰性结果......函数/谓词仅在需要时才应用,因为使用对象。他们不创建副本。但正因为如此,转换很容易违反
Set
的要求。例如,假设您有一个
Map
,其中同时包含“1”和“01”作为键。它们都是不同的String
,因此Map
可以合法地将两者包含为键。但是,如果使用Long.valueOf(String)
转换它们,它们都会映射到值1
。它们不再是不同的键。如果您创建地图的副本并添加条目,这不会破坏任何内容,因为任何重复的键都会覆盖该键的先前条目。但是,惰性转换的Map
无法强制执行唯一键,因此会破坏Map
的约定。@Vivin's answer is correct, but I think it's useful to explain why Guava doesn't have any method to allow you to transform the keys of a
Map
(or to transform aSet
at all).All of Guava's methods for transforming and filtering produce lazy results... the function/predicate is only applied when needed as the object is used. They don't create copies. Because of that, though, a transformation can easily break the requirements of a
Set
.Let's say, for example, you have a
Map<String, String>
that contains both "1" and "01" as keys. They are both distinctString
s, and so theMap
can legally contain both as keys. If you transform them usingLong.valueOf(String)
, though, they both map to the value1
. They are no longer distinct keys. This isn't going to break anything if you create a copy of the map and add the entries, because any duplicate keys will overwrite the previous entry for that key. A lazily transformedMap
, though, would have no way of enforcing unique keys and would therefore break the contract of aMap
.Java 8 的更新
您可以使用流来执行此操作:
这假设所有键都是
Long
的有效字符串表示形式。另外,变形时可能会发生碰撞;例如,"0"
和"00"
都映射到0L
。我认为您必须迭代地图:
此代码假设您已经清理了
map
中的所有值(因此没有无效的长值)。我希望有更好的解决方案。
编辑
我遇到了从头开始,它只是适用于实现CollectionUtils#transformedCollection(Collection, Transformer)
方法看起来可能会执行您想要的操作。Collection
的类。UPDATE for Java 8
You can use streams to do this:
This assumes that all keys are valid string-representations of
Long
s. Also, you can have collisions when transforming; for example,"0"
and"00"
both map to0L
.I would think that you'd have to iterate over the map:
This code assumes that you've sanitized all the values in
map
(so no invalid long values).I'm hoping there is a better solution.
EDIT
I came across theScratch that, it only works for classes that implementCollectionUtils#transformedCollection(Collection, Transformer)
method in Commons Collection-Utils that looks like it might do what you want.Collection
.现在,您可以使用 Java 8 流、映射、收集以更易读、更简洁的方式执行此操作。
You can now use Java 8 stream, map, collect to do this in a more readable, clean manner.
这是下面答案之一的更新版本,使生成的 Map 不可修改(不,它不使用 Guava,只是普通的 Java 8):
Here's an updated version of one of the answers below to make the resulting Map unmodifiable (no, it's not using Guava, just plain Java 8):
简短的回答是否定的,Guava 不提供开箱即用的功能。
简单的方法如下所示。不过,也有一些警告。
Guava 的 Transformer 都是“惰性的”或者基于视图的。我认为要实现地图键转换器,您需要一个双向功能。我的理解是,Guava 团队正在开发一个 Converter,它可以解决这个问题。
您遇到的另一个问题是,您必须处理重复的可能性才能“防吉米”,另一个 Guava 原则。处理该问题的一种方法是返回 多重地图;另一种方法是在遇到重复项时抛出异常。我不建议隐藏问题,例如通过忽略具有重复键的后续条目,或通过使用重复键覆盖新条目。
The short answer is no, Guava does not provide this one out of the box.
The simple way would be something like below. There are some cautions, however.
Guava's transformers are all "lazy" or view-based. I think to implement a map key transformer, you'd want a two-way function. My understanding is that there is a Converter that is in the works by the Guava team, which would solve that problem.
The other problem you run into is that you'd have to deal with the possibility of duplicates in order to be "Jimmy-proof", another Guava principle. One way to handle that would be to return a Multimap; another would be to throw an exception when you encounter duplicates. What I would not suggest is hiding the problem e.g. by ignoring subsequent entries with duplicate keys, or by overwriting the new entry with the duplicate key.
使用 Java 8 和 jOOλ 进行回答
Answer using Java 8 and jOOλ