-1

I have a method called sortTest() that takes in a number and a sortName(). The number that it will take in will become the size of the array created and sortName() is supposed to be the name of the sort it will do.

For example, if I have sortTest(5, bubbleSort) it should create an array of 5 with random numbers and then take that array of 5 through bubble sort. Here is my code:

public static final int loopSize = 16; 
    public static int[] makeArray(int n) { 
        int[] array = new int[n]; 

        for(int d = 0; d < loopSize; d++ ) { 

            Random r = new Random(); 

            for(int i = 0; i < n; i++) { 

                for(int k = 0; k < n; k++) { 

                    array[k] = (int)( Math.random()* 1000); 

                } 

            } 

        } 

        return array; 

    } 

public static void sortTest(int num , sortName() ) { 

    long Finaltime []; 

    for(int k = 0; k < loopSize; k++ ) { 

        arr = makeArray(num); 

        long startTime = System.nanoTime(); 

        sortName(arr); 

        endTime = System.nanoTime(); 

        totalTime = endTime - startTime; 

    } 

} 
Rubii
  • 1
  • 3
  • Simple answer, NO. You can call `sortName()` outside of the `sortTest` and then pass the result to the `sortTest` method, or you can change the `sortTest` method to `public static void sortTest(int num , int sortType) ) {`, and then use an IF statement inside your `sortTest` method to call the right sort depending on the `sortType`. – sorifiend Sep 24 '18 at 02:45
  • 1
    I'm not sure if this is what you want, but you could make the second parameter a [`Consumer`](https://docs.oracle.com/javase/10/docs/api/java/util/function/Consumer.html)? – Slaw Sep 24 '18 at 02:52
  • You've received 3 answers and several comments but have not accepted or acknowledged any of the contributions made by anyone. Please consider correcting this. – Hovercraft Full Of Eels Oct 31 '18 at 02:37

3 Answers3

3

There are a lot of different ways to do it. You might want to check out the Functional documentation: https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

In your case you probably want to change your top level function to a consumer of other functions.

Something like:

public static void sortTest(int num, BiFunction<Integer, Integer, Integer> sortFunction) {...}

(In this case it is BiFunction or calling it sortFunction.apply(int, int) returning an int

The functional interfaces are a bit "clunky" in Java but they work fine (and have been around in one form or another for quite some time). With Java 1.8 and later there is a bit more formal support for lambdas which make them more usable.

Fundamentally this is just an interface that happens to be a function. You could then create sort functions with different names:

BiFunction<Integer, Integer, Integer> ascending = (a,b) -> { ... return sort; //-1 0 1};
BiFunction<Integer, Integer, Integer> descending = (a,b) -> { return ascending.apply(b, a) };
...etc...

These could then be passed to your static method:

...
YourClass.sortTest(10, ascending)
...

Hopefully that points you in the right direction. It looks like you're new to Java, don't be afraid to ask questions.

Daniel B. Chapman
  • 4,647
  • 32
  • 42
  • I think you mean `BiFunction`, not `BiConsumer` - `BiConsumer` has just two type parameters, not three, and it doesn't return anything. But why not just use `Comparator`? This is exactly what it's for. – Dawood ibn Kareem Sep 24 '18 at 19:21
  • @DawoodibnKareem You're correct, that's a type-o on my part. I chose BiFunction simply to be more generic as it seemed like this was more of a functional programming question. – Daniel B. Chapman Sep 24 '18 at 21:40
0

Note: This answer is based on Java 8 and newer. This does not apply to Java 7, as Java 7 does not support Lambda

Define the SortType interface

interface SortType {
    void sortName(int[] data);
}

Write test cases

public class Test {
    public static final int loopSize = 16;

    public static int[] makeArray(int n) {
        int[] array = new int[n];
        for (int d = 0; d < loopSize; d++) {
            Random r = new Random();
            for (int i = 0; i < n; i++) {
                for (int k = 0; k < n; k++) {
                    array[k] = (int) (Math.random() * 1000);
                }
            }
        }
        return array;
    }

    // Pass functional SortType interface
    public static void sortTest(int num, SortType sortType) {

        long Finaltime[];
        for (int k = 0; k < loopSize; k++) {
            int[] arr = makeArray(num);
            long startTime = System.nanoTime();
            sortType.sortName(arr);
            long endTime = System.nanoTime();
            long totalTime = endTime - startTime;
        }
    }
}

Execute test case using main method

public static void main(String[] args) {
        // define which algorithm need to call
        SortType bubbleSort = (int[] data) -> Arrays.sort(data);
        SortType bubbleSortOnlyLastThree = (int[] data) -> Arrays.sort(data, 2, 5);
        sortTest(5, bubbleSort);
        sortTest(5, bubbleSortOnlyLastThree);
    }
Hardik
  • 1,519
  • 1
  • 10
  • 10
  • Actually, the only thing that is Java 8 specific is the Lambda in the call. In Java < 8 you can simply use an anonymous inner class instead. – jokster Sep 24 '18 at 06:07
-1

No, you can't pass your sortName() method as a parameter to another method (not like that, at least), nor should you. I think the best solution in your case is to use a static method.

In Java, a static method is called directly, without the need of creating an instance (object) of the class that contains it (read the answers to this question for more details). In this context, you could declare sortName() as follows:

public MyClass {
    public static void sortName(long[] array) {
        //your code here
    }
}

Then, whenever you need to call it outside MyClass, all you need to do is use the following syntax: MyClass.sortName(myArray). In your code, it would look like this:

public static void sortTest(int num) { 
    //...
    MyClass.sortName(arr);
    //...
} 
Talendar
  • 1,841
  • 14
  • 23
  • This way, the sorting algorithm is hard-coded. That is not what the OP wanted! – jokster Sep 24 '18 at 06:06
  • If that was the case, then my approach would indeed not be appropriate. However, it's not clear to me whether or not the OP wants `sortName()` to be "dynamic". If you disagree, please, point me out to where in his question he said that, so I can revise my answer. Otherwise, I still believe that the use of a *static method* is more suitable for the OP's situation, since it seems that he is a beginner just trying to find a way to make his code work. – Talendar Sep 24 '18 at 06:14
  • I get that impression from `sortName()` being passed as a parameter. To me, that implies that it is not constant but can have different values. – jokster Sep 25 '18 at 07:22
  • 1
    Indeed. When I first read the question, this specific point was a source of confusion to me. After reflecting, I decided to give an answer explaining the simplest way to achieve what the OP apparently wanted. Since he is a beginner, I didn't think that he was trying to pass the actual method as an argument. Anyway, unless he says something, we can't really know for sure. At least there are other answers covering what mine lack. – Talendar Sep 25 '18 at 07:36