Jacob Birkett
Jacob Birkett

Reputation: 2125

Spread an array into multiple arguments for a function

How can I pass an array as three arguments to a function in Java? (Forgive me, I'm very new to Java).

I have the following function which takes float r, float g, float b, float a as arguments.

renderer.prepare(r, g, b, 1);

And I want to pass the output from this function in. (Or figure out how to return three separate unpacked floats).

public static float[] rgbToFloat(int r, int g, int b) {
    return new float[] {(float) r / 255f, (float) g / 255f, (float) b / 255f};
}

How can I do this? In some other languages it would look something like this:

renderer.prepare(...rgbToFloat(25, 60, 245), 1); 

Upvotes: 10

Views: 2544

Answers (2)

Mike Nakis
Mike Nakis

Reputation: 62045

This is a typical example of an "X-Y Problem". Your original quest was to somehow group the 3 different parameters that you want to pass to a function. That's "problem X". Then you came up with the idea of using an array for this, but you were still unsure how to go about it, so you posted this question asking how to best use an array to achieve what you want. But that's "problem Y", not "problem X".

Using an array may and may not be the right way of solving "problem X". (Spoiler: it isn't.)

Honoring the principle of the least surprise, the best way of solving your problem "X" in my opinion is by declaring a new class, FloatRgba which encapsulates the four floats in individual float members: final float r; final float g; final float b; final float a;.

So, then your rgbToFloat() method does not have to return an unidentified array of float, instead it becomes a static factory method of FloatRgba:

public static FloatRgba fromIntRgb( int r, int g, int b ) 
{
    return new FloatRgba( r / 255f, g / 255f, b / 255f, 1.0f );
}

Finally, you introduce a utility function prepareRenderer which accepts a Renderer and a FloatRgba and invokes renderer.prepare(float, float, float, float) passing it the individual members of FloatRgba.

This way you keep everything clear, self-documenting, and strongly typed. Yes, it is a bit inconveniently verbose, but that's java for you.

Upvotes: 2

Aconcagua
Aconcagua

Reputation: 25536

Maybe late for the original question, might help late readers stumbling over here (like me), though: I rather recommend converting just one single parameter to float:

public static float rgbToFloat(int value)
{
    return value / 255.0f;
    // don't need the cast, value will be promoted to float anyway
    // as second parameter is already
}

Call now gets to

 renderer.prepare(rgbToFloat(25), rgbToFloat(60), rgbToFloat(245), 1);

Sure, the draw back is that you have to call it three times now (as the other way round, you would have had to store the array in a temporary as shown in the comments, you wouldn't, in comparison, have gained much either), in the end, you gain flexibility for and additionally avoid the temporary array object when none is needed.

If you still insist on the array, you'll need a temporary

float[] rgb = rgbToFloat(r, g, b);
renderer.prepare(rgb[0], rgb[1], rgb[2], 1.0f);

But then I wonder why you don't consider alpha as well:

public static float[] rgbToFloat(int r, int g, int b)
{
    return rgbToFloat(r, g, b, 255);
}
public static float[] rgbToFloat(int r, int g, int b, int a)
{
    return new float[] { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
}

Upvotes: 0

Related Questions