将 Set 转换为 List 而不创建新 List
我正在使用此代码将 Set
转换为 List
:
Map<String, List<String>> mainMap = new HashMap<>();
for (int i=0; i < something.size(); i++) {
Set<String> set = getSet(...); //returns different result each time
List<String> listOfNames = new ArrayList<>(set);
mainMap.put(differentKeyName, listOfNames);
}
我想避免在循环的每次迭代中创建新列表。这可能吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
您可以使用 List.addAll() 方法。它接受一个 Collection 作为参数,并且您的集合是一个 Collection。
编辑:作为对问题编辑的回应。
很容易看出,如果你想要一个以
List
作为值的Map
,为了有k个不同的值,你需要创建k个不同的值列表。因此:您根本无法避免创建这些列表,必须创建这些列表。
可能的解决方法:
将您的
Map
声明为Map
或Map
,然后插入您的集合。You can use the List.addAll() method. It accepts a Collection as an argument, and your set is a Collection.
EDIT: as respond to the edit of the question.
It is easy to see that if you want to have a
Map
withList
s as values, in order to have k different values, you need to create k different lists.Thus: You cannot avoid creating these lists at all, the lists will have to be created.
Possible work around:
Declare your
Map
as aMap<String,Set>
orMap<String,Collection>
instead, and just insert your set.使用构造函数来转换它:
Use constructor to convert it:
同样在 Guava Collect 库中,您可以使用
newArrayList(Collection)
:这与 amit 之前的答案非常相似,只是您不需要声明(或实例化)任何
list
对象。Also from Guava Collect library, you can use
newArrayList(Collection)
:This would be very similar to the previous answer from amit, except that you do not need to declare (or instanciate) any
list
object.我们可以在 Java 8 中使用以下一个衬线:
这是一个小示例:
注意: 这种使用流创建的方式会产生内存损失。如果需要避免创建新内存,则避免使用此解决方案
We can use following one liner in Java 8:
Here is one small example:
Note: This way of creating using streams has a memory penalty. If need is to avoid creating new memory, then avoid this solution
我想要一种非常快速的方法将我的集合转换为列表并返回它,所以我在一行中做了
I wanted a very quick way to convert my set to List and return it, so in one line I did
由于到目前为止尚未提及,从 Java 10 开始,您可以使用新的
copyOf
工厂方法:来自 Javadoc:
请注意,这会创建一个新列表(
ImmutableCollections$ListN
准确地说,通过在Collection#toArray()
然后Since it hasn't been mentioned so far, as of Java 10 you can use the new
copyOf
factory method:From the Javadoc:
Note that this creates a new list (
ImmutableCollections$ListN
to be precise) under the hood byCollection#toArray()
on the given set and then为了完整起见......
假设您确实确实希望将
Map
值视为List
,但您希望避免复制每次将Set
放入List
中。例如,也许您正在调用一个创建
Set
的库函数,但您将Map>
结果传递给一个(很差-设计但不在你手中)只需要Map>
的库函数,即使你以某种方式知道它对List
同样适用于任何Collection
(因此也适用于任何Set
)。 由于某种原因,您需要避免将每个集合复制到列表的速度/内存开销。在这种超级利基的情况下,根据库函数在您的
List
中需要的(可能不可知的)行为,您也许能够创建一个List
视图 在每组上。请注意,这本质上是不安全的(因为每个List
中的库函数的要求可能会在您不知情的情况下发生变化),因此应首选其他解决方案。但你可以这样做。您将创建一个实现
List
接口的类,在构造函数中采用Set
并将该 Set 分配给一个字段,然后使用该内部Set< /code> 实现
List
API(在可能的情况下和需要的范围内)。请注意,如果不将元素存储为
List
,您将无法模仿某些列表行为,而您只能部分模仿某些行为。同样,一般来说,此类并不是 List 的安全替代品。特别是,如果您知道用例需要与索引相关的操作或修改List
,那么这种方法很快就会失败。For the sake of completeness...
Say that you really do want to treat the
Map
values asList
s, but you want to avoid copying theSet
into aList
each time.For instance, maybe you are calling one library function that creates a
Set
, but you are passing yourMap<String, List<String>>
result to a (poorly-designed but out of your hands) library function that only takesMap<String, List<String>>
, even though somehow you know that the operations it does with theList
s are equally applicable to anyCollection
(and thus anySet
). And for some reason you need to avoid the speed/memory overhead of copying each Set to a List.In this super niche case, depending on the (maybe unknowable) behavior the library function needs out of your
List
s, you may be able to create aList
view over each Set. Note that this is inherently unsafe (because the library function's requirements from eachList
could presumably change without you knowing), so another solution should be preferred. But here's how you'd do it.You'd create a class that implements the
List
interface, takes aSet
in the constructor and assigns that Set to a field, and then uses that internalSet
to implement theList
API (to the extent possible, and desired).Note that some List behavior you simply will not be able to imitate without storing the elements as a
List
, and some behavior you will only partially be able to imitate. Again, this class is not a safe drop-in replacement forList
s in general. In particular, if you know that the use case requires index-related operations or MUTATING theList
, this approach would go south very fast.我会这样做:
I would do :
您可以使用这一行更改:
Arrays.asList(set.toArray(new Object[set.size()]))
You could use this one line change:
Arrays.asList(set.toArray(new Object[set.size()]))
Java 8 提供了使用流的选项,您可以从
Set 获取列表。 setString
as:虽然目前内部实现提供了
ArrayList
的实例:但JDK并不保证它。正如这里提到的:
如果您想始终确保,那么您可以专门请求一个实例,如下所示:
Java 8 provides the option of using streams and you can get a list from
Set<String> setString
as:Though the internal implementation as of now provides an instance of
ArrayList
:but JDK does not guarantee it. As mentioned here:
In case you want to be sure always then you can request for an instance specifically as:
我创建简单的
static
方法:...或者如果您想设置列表类型,您可以使用:
I create simple
static
method:... or if you want to set type of List you can use:
最近我发现了这个:
Recently I found this:
我发现这工作正常并且对于从集合创建列表很有用。
I found this working fine and useful to create a List from a Set.
您可以将
Set
转换为List
,而无需添加排序信息(例如排序),只是将其存储在地图中。因为
Set
是无序的,并且没有添加排序信息,所以不应该使用List
,因为它将包含随机排序的数据,并且所有与有序数据相关的方法都将被模糊的。您应该使用
Collection
接口,它在地图中同时接受Set
和List
。这样,当您使用多态性而不是复制数据时,不需要额外的内存。You convert
Set
toList
without adding ordering information (like sorting) just to store it in the map.Because
Set
is unordered and no ordering information is added,List
should not be used, as it will contain randomly ordered data and all it's methods that are related to ordered data will be ambiguous.You should use
Collection
interface instead, that accepts bothSet
andList
in the map. This way, no additional memory is required as you use polymorphism instead of copying data.