0

I want to make a simple program to compare how long time takes rewrite and print out collection of Strings by `for loop`, `foreach` or `stream`. String is sentence where it replaces "i" by "y". In my case I made `count()` where I set to count `stream()` method but I want to make universal measuring method. But i dont know how to do it... It should works like: in Main class is `counter(forLoop);` It should call `forLoop();` from Method class
`counter(forEach);` It should call `forEach();` from Metrod class
`counter(stream);` It should call ` stream();` From Method class

IDont know how to pass method as a parameter

I have class where are those metods:

import java.util.*;
import java.util.stream.*;

public class Methods {

    private List<String> sentence = new ArrayList<>();
    private String oldLetter = "i";
    private String newLetter = "y";

    private String methodType;

    public String getMethodType() {
        return methodType;
    }
//making a collection with String
    public void setSizeOfCollection(int size){
        for (int i = 0; i < size; i++) {
            sentence.add("Siti Zbinek plitce zvikal sirovi pelinek.");
        }
    }

    public void forLoop(){
        methodType = "For loop";
        for (int i = 0; i < sentence.size(); i++) {
            for (int j = 0; j < sentence.size(); j++) {
                String replaceLetters = sentence.get(j);
                replaceLetters = replaceLetters.replaceAll(oldLetter, newLetter);
                sentence.set(j, replaceLetters);
            }
            System.out.println(sentence.get(i));
        }
    }

    public void forEach(){
        methodType = "For each";
        String replacedLetters = "";
        for(String oneLine: sentence){
            for(String originalLetters: sentence){
                replacedLetters = originalLetters.replaceAll(oldLetter,newLetter);
            }
            System.out.println(replacedLetters);
        }
    }
    public void stream(){
        methodType= "Stream";
        sentence.stream()
                .map(e->e.replaceAll(oldLetter,newLetter))
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }
}

This is count() that works fine, but only for method stream(). In comment is my imagine how it should be. But I dont know how it do by Java :(

import org.apache.commons.lang.time.*;
public class Counter {
     private Methods methods;
     private String methodType;
     private  StopWatch stopWatch = new StopWatch();
    long timeTaken = 0;

//here should be something like any method as a parameter XXX xxx
// public void count(Methods methods XXX xxx)

    public void count(Methods methods){
     stopWatch.start();

//   here sould be something what call any function by your choice, not only stream()
 //  methods.xxx; 

     methods.stream();

     stopWatch.stop();
     timeTaken= stopWatch.getTime();
     System.out.println(methods.getMethodType()+" takes "+ timeTaken + " ms." );
 }
}

And finally Main class

public class Main {
    public static void main(String[] args) {

        Methods methods = new Methods();
        Counter counter = new Counter();

        methods.setSizeOfCollection(10000);

        counter.count(methods);
//here should be finally three times method, with  different parameters:
//      counter.count(methods, forEach);
//      counter.count(methods, forLoop);
//      counter.count(methods, stream);

    }
}

Any advice please?

  • Does this answer your question? [How do I define a method which takes a lambda as a parameter in Java 8?](https://stackoverflow.com/questions/13604703/how-do-i-define-a-method-which-takes-a-lambda-as-a-parameter-in-java-8) – Herry Sep 21 '22 at 13:30
  • You could declare count() to accept a Runnable, then pass either classes that implement Runnable, or a lambda like `() -> doSomething();` – Andy Thomas Sep 21 '22 at 13:31
  • 1
    You probably want to read [How do I write a correct micro-benchmark in Java](https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java). – daniu Sep 21 '22 at 13:53
  • 1
    @AndyThomas or use a method reference: `methods::stream`, `methods::forEach`, `methods::forLoop`. – Rob Spoor Sep 21 '22 at 14:50

2 Answers2

0

All your methods have the signature void(). Consequently, a reference to each method can be stored in a Runnable instance.

public void count(final Runnable method) {
    stopWatch.start();

    method.run();

    stopWatch.stop();
    timeTaken= stopWatch.getTime();
    System.out.println(methods.getMethodType()+" takes "+ timeTaken + " ms.");
}

And then call as:

final Methods methods = new Methods();
final Counter counter = new Counter();

methods.setSizeOfCollection(10000);

counter.count(methods::stream);  // or count(() -> methods.stream());
counter.count(methods::forEach); // count(() -> methods.forEach());
counter.count(methods::loop);    // count(() -> methods.loop());

To be able to use method refs or lambdas, you need to have at least Java 8. For earlier Java versions, you would need to implement Runnable with an anonymous class, e.g.

counter.count(new Runnable() {
  @Override public void run() { methods.stream(); }
});

or look up the methods by name via Reflection, but Reflection is usually the slowest option.

PS. Note however that your way of measuring method execution times is flawed; see How do I write a correct micro-benchmark in Java? for directions. This answer only explains the part of passing "methods" to another method.

knittl
  • 246,190
  • 53
  • 318
  • 364
-2

you could pass the method name as a string and look for it with reflexion.

  • 1
    Since Java 8, reflection (not "reflexion") is hardly ever the correct answer (and before it was still dubious). Lambdas and method references can be used instead in most of the cases. – Rob Spoor Sep 21 '22 at 14:49
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 26 '22 at 15:07