Home > Mobile >  Generic Supplier for n Getters Across Collection
Generic Supplier for n Getters Across Collection

Time:01-29

I have a collection of Java objects where I want to run a single function across multiple values I might find in some of the object's member variables. I'm looking for a nice way to pass in which getter should be used so I can have one method do all that work. I was thinking about something like a Supplier, but that would mean I have to have one per instance of the class. Here's an example of what I'm trying to do (only I would like to do this without the if statement or with potentially n getters a switch statement:

import java.util.ArrayList;
import java.util.List;

public class TestSupplier {
   private int varA;
   private int varB;

   public TestSupplier(int varA, int varB) {
      this.varA = varA;
      this.varB = varB;
   }

   public int getA() {
      return this.varA;
   }

   public int getB() {
      return this.varB;
   }

   public static void main(String[] args) {
      List<TestSupplier> testList = new ArrayList<>();
      testList.add(new TestSupplier(1, 11));
      testList.add(new TestSupplier(2, 22));
      // Can I pass something like a generic supplier instead of a bool?
      TestSupplier.someCollectorFunction(testList, true);
      TestSupplier.someCollectorFunction(testList, false);
   }

   public static void someCollectorFunction(List<TestSupplier> list, boolean isA /* what if I want more than one getter*/) {
      int sum = 0;
      for (TestSupplier obj: list) {
         // This is where I wish I could have a generic supplier or something
         if (isA) {
            sum = sum   obj.getA();
         }
         else {
            sum = sum   obj.getB();
         }
      }
      System.out.println("I have a sum: "   sum);
   }
}

Is there something is Java's functional API that would let me do this?

CodePudding user response:

It sounds like what you want is

ToIntFunction<TestSupplier> fn = isA ? TestSupplier::getA : TestSupplier::getB;
for (TestSupplier obj: list) {
  sum  = fn.applyAsInt(obj);
}

It's up to you whether you consider that an improvement.

You could also pass in the ToIntFunction instead of the boolean, passing in TestSupplier::getA instead of true etc.

  • Related