Object creating and invoking using method reference

Viewed 47

I wanted to understand :: operator a bit more, and with this intention, created a sample program:


public class Second {

    public static void main(String[] args) {

        doWork(new int[] { 1, -1, 2, -1, 0, 2, 0, 0 });

    }

    public static void doWork(int[] nums) {

        // This is a compilation error - how do
        // we create an object and invoke method?
        Arrays.stream(nums).forEach((Myclass1::new)::print);  
    }


    @FunctionalInterface
    interface MyInterf1 {
        public abstract void print(int i);
    }

    public class Myclass1 implements MyInterf1 {

        private int i;

        public Myclass1(int i) {
            this.i = i;
        }

        @Override
        public void print(int i) {
            System.out.println(this.i);
        }
    }
   }

My intent is simple:

To print each element, using "::" to invoke the print() method of Myclass1. As this method is non-static, so I need to first create the object of this class and then invoke.

Is it possible at all? How do we simplify both object creation (using::) and then invoking method on that object?

1 Answers

Your print method doesn't need the i argument, since it ignores it and prints the instance variable this.i.

And I'd change Myclass1 to be a static class, so that you don't have to worry about an enclosing instance of Second class.

Now you can write:

class Second {

    public static void main(String[] args) {

        doWork(new int[] { 1, -1, 2, -1, 0, 2, 0, 0 });

    }

    public static void doWork(int[] nums) {

        Arrays.stream(nums).mapToObj(Myclass1::new).forEach (Myclass1::print);

    }


    @FunctionalInterface
    interface MyInterf1 {
        public abstract void print();
    }

    public static class Myclass1 implements MyInterf1 {

        private int i;

        public Myclass1(int i) {
            this.i = i;
        }

        @Override
        public void print() {
            System.out.println(this.i);
        }
    }
}

Explanation:

First, Arrays.stream(nums) creates an IntStream.

Then, mapToObj(Myclass1::new) transforms each int to a Myclass1 instance by passing the int to the Myclass1(int i) constructor. This results in a Stream<Myclass1>.

Finally, forEach(Myclass1::print) prints the int values by calling the print() method of each Myclass1 instance.

Related