10

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); 
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Jacob Birkett
  • 1,927
  • 3
  • 24
  • 49
  • 2
    Why not save it as a middle gorund and then you can pass it as `rbgToFloat(array[0], array[1], array[2])`. You can `float[] tmp = rgbToFloat()` and then `prepare(tmp[0], tmp[1], tmp[2], 1)` – ZeldaZach Jul 01 '17 at 19:34
  • You have to unpack it manually. Sorry. – khelwood Jul 01 '17 at 19:35
  • Okay. It seems odd that Java doesn't have this ability, I see it everywhere else. – Jacob Birkett Jul 01 '17 at 19:39
  • If the function receives an array of elements instead of each element separately, you can use a similar syntax to what you are trying to do. [Take a look at it here](https://stackoverflow.com/questions/5405673/java-varags-method-param-list-vs-array) – Isac Jul 01 '17 at 19:44

2 Answers2

2

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.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 1
    A less complex solution might be letting the `prepareRenderer` simply accept the renderer and three ints. Good spot on the X/Y problem ;) – Aconcagua Jul 08 '20 at 14:52
0

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 };
}
Aconcagua
  • 24,880
  • 4
  • 34
  • 59