ChatGPT解决这个技术问题 Extra ChatGPT

How to pass an ArrayList to a varargs method parameter?

Basically I have an ArrayList of locations:

ArrayList<WorldLocation> locations = new ArrayList<WorldLocation>();

below this I call the following method:

.getMap();

the parameters in the getMap() method are:

getMap(WorldLocation... locations)

The problem I'm having is I'm not sure how to pass in the WHOLE list of locations into that method.

I've tried

.getMap(locations.toArray())

but getMap doesn't accept that because it doesn't accept Objects[].

Now if I use

.getMap(locations.get(0));

it will work perfectly... but I need to somehow pass in ALL of the locations... I could of course make keep adding locations.get(1), locations.get(2) etc. but the size of the array varies. I'm just not use to the whole concept of an ArrayList

What would be the easiest way to go about this? I feel like I'm just not thinking straight right now.


a
aioobe

Source article: Passing a list as an argument to a vararg method

Use the toArray(T[] arr) method.

.getMap(locations.toArray(new WorldLocation[0]))

Here's a complete example:

public static void method(String... strs) {
    for (String s : strs)
        System.out.println(s);
}

...
    List<String> strs = new ArrayList<String>();
    strs.add("hello");
    strs.add("world");
    
    method(strs.toArray(new String[0]));
    //     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

How costly this operation would be in terms of memory & speed?
This will not work without a warning if there are further templates involved. E.g. someMethod(someList.toArray(new ArrayList<Something>[someList.size()])) will give you a warning that is very annoying if the function is more than a few lines long (because you can either suppress it for the whole function or you have to create the array in an additional step and suppress the warning on the variable you store it.
Apparently the fastest approach is giving a size of zero rather than the size of the array. In short, it's because the compile-time constant enables the use of an optimized method. shipilev.net/blog/2016/arrays-wisdom-ancients
@JoshM. Java needs a lot of things. ;) I also (coming from a C# background) miss index operators. Working with dictionaries is much more smooth in C# than working with HashMaps in Java.
@PerLundberg -- Totally agree. Also a primarily C# developer currently working w/Java8. Maybe 10/11 will be better. :-P
j
jmhostalet

In Java 8:

List<WorldLocation> locations = new ArrayList<>();

.getMap(locations.stream().toArray(WorldLocation[]::new));

this is java voodoo, but better java (8) voodoo.. thanks!
locations.toArray(WorldLocations[]::new) also seems to works since java 11 (Without the .stream())
@EranMedan toArray works always without stream, regardless of the Version see: docs.oracle.com/javase/1.5.0/docs/api/java/util/List.html
@kaba713 yes, but not the overload that accepts an IntFunction, which was added in Java 11 :) docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/…
t
tkruse

A shorter version of the accepted answer using Guava:

.getMap(Iterables.toArray(locations, WorldLocation.class));

can be shortened further by statically importing toArray:

import static com.google.common.collect.toArray;
// ...

    .getMap(toArray(locations, WorldLocation.class));

This answer worked for me since I wanted an array of Lists, but couldn't instantiate a generic array in order to use Array.toArray.
* List.toArray
S
Sylhare

You can do:

getMap(locations.toArray(new WorldLocation[locations.size()]));

or

getMap(locations.toArray(new WorldLocation[0]));

or

getMap(new WorldLocation[locations.size()]);

@SuppressWarnings("unchecked") is needed to remove the ide warning.


2nd solution is better!
Third solution gives a blank array, don't use it.
N
Nikhilesh Patve

Though it is marked as resolved here my KOTLIN RESOLUTION

fun log(properties: Map<String, Any>) {
    val propertyPairsList = properties.map { Pair(it.key, it.value) }
    val bundle = bundleOf(*propertyPairsList.toTypedArray())
}

bundleOf has vararg parameter


This is a great answer for kotlin, but it is unlikely to help many people since the question is tagged java