TIL: Variable Number of Parameters in Methods

We’re going to build off of the method discussion from yesterday a bit more and cover the topic of sending n number of parameters of a specific type to a method.

There are occasions where you might want to support anywhere from 1 to n number of a type of parameter in a method. In the case of the Flight class example from yesterday, maybe we want to be able to register more than just a single person at a time to the plane.

Now, we could do this the hard way. We could write a specific method that will take in an array of Passenger objects, but that creates even more work for us on our end. Now we need to take the time to actually build an array to send.

Rather than do that, java makes it easy to define when more than one value of a parameter can be accepted.

Note:

If you need a refresher on what the Flight and Passenger classes look like, either go back to the previous posts or take a look at the code in the repo.

Supporting n Parameters

In order to denote that you want to accept 1-n of a specific parameter, you can do so by using ... ellipses after the type in your method definition. For instance, if I wanted to write a new method inside of the Flight class that would allow me to accept more than one parameters, I could do something like this:

1
2
3
4
5
public void addNPassengers(Passenger... passengers) {
   for(Passenger p: passengers) {
       add1Passenger(p.getCheckedBags());
   }
}

This syntax denotes that we’re going to support any number of passengers that get passed to us. And because we use this syntax, we only need to list the objects out like normal parameters when calling the method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Test
public void add2Passengers() {
   Flight f1 = new Flight();
   Passenger bob = new Passenger(2, 4);
   Passenger jane = new Passenger(0, 1);
   f1.addNPassengers(bob, jane);
   Assert.assertEquals(2, f1.getPassengers());
   Assert.assertEquals(0, f1.getTotalCarryOns());
   Assert.assertEquals(5, f1.getTotalCheckedBags());
}

If we didn’t use the ... to denote that multiple parameters were accepted, and instead used an array of Passengers as our input, we would have to change our call a little bit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Test
public void add2PassengersArray() {
   Flight f1 = new Flight();
   Passenger bob = new Passenger(2, 4);
   Passenger jane = new Passenger(0, 1);
   f1.addNPassengers(new Passenger[] {bob, jane});
   Assert.assertEquals(2, f1.getPassengers());
   Assert.assertEquals(0, f1.getTotalCarryOns());
   Assert.assertEquals(5, f1.getTotalCheckedBags());
}

Note that by switching to the ... format, the above will still work!

Supporting n Parameters WITH Other Parameters

So while this is a nice feature, it does come with a major(?) drawback to it.

Because we aren’t defining the size or providing a container, there’s no way to specify the number of objects that you’re sending in… so in turn your method wouldn’t really know how to distinguish between multiple sets of multiple parameters.

You can only use the variable definition on the last parameter inside of a method. So there’s no way to have 3 parameters on your method, all of which accept n number of values (unless you go back to defining arrays).

So what does this look like? Well let’s say we want to expand our method from before a bit more, and maybe create another overload method that would allow us to put in both n number of Passengers as well as the number of carry on bags they all have. We could do something like this:

1
2
3
4
5
public void addNPassengers(int carryOns, Passenger... passengers) {
   for(Passenger p: passengers) {
       add1Passenger(p, carryOns);
   }
}

Notice how the number of carry on bags comes BEFORE the Passenger list.

💚 A.B.L.