InsertionSort -> aufsteigend as default, absteigend as non-default

import java.util.Arrays;
import java.util.Random;
import java.util.function.BiFunction;

public class InsertionSort {
	public static void insertionSort(int[] a ) {
		BiFunction<Integer, Integer, Boolean> c1 = (i, j) -> i > j;
		BiFunction<Integer, Integer, Boolean> c2 = (i, j) -> i < j; // absteigend
		final int n = a.length;
		for (int j = 1; j < n; j++) {
			int key = a[j];
			int i = j - 1;
			while (i > -1 && c1.apply(a[i], key)) {
				a[i + 1] = a[i];
				i--;
			}
			a[i + 1] = key;
		}
	}

	public static void main(String[] args) {
		Random rd = new Random(1);
		int arr[] = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = rd.nextInt();
			System.out.println(arr[i]);
		}

		insertionSort(arr);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr);
		System.out.println(Arrays.toString(arr));
	}
}

Gibt es Default-Parameter bzw. -Argumente?

Wäre das hier die einzige Möglichkeit?:

import java.util.Arrays;
import java.util.Random;
import java.util.function.BiFunction;

public class InsertionSort {
	public static enum SortOrder {
		AUFSTEIGEND(true), ABSTEIGEND(false);

		private BiFunction<Integer, Integer, Boolean> o;

		private SortOrder(boolean aufsteigend) {
			if (aufsteigend) {
				o = (i, j) -> i > j;
			} else {
				o = (i, j) -> i < j;
			}
		}

		public BiFunction<Integer, Integer, Boolean> getO() {
			return o;
		}
	}

	public static void insertionSort(int[] a) {
		insertionSort(a, SortOrder.AUFSTEIGEND);
	}

	public static void insertionSort(int[] a, SortOrder o) {
		BiFunction<Integer, Integer, Boolean> c = o.getO();

		final int n = a.length;
		for (int j = 1; j < n; j++) {
			int key = a[j];
			int i = j - 1;
			while (i > -1 && c.apply(a[i], key)) {
				a[i + 1] = a[i];
				i--;
			}
			a[i + 1] = key;
		}
	}

	public static void main(String[] args) {
		Random rd = new Random(1);
		int arr[] = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = rd.nextInt();
			System.out.println(arr[i]);
		}

		insertionSort(arr);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr, SortOrder.ABSTEIGEND);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr, SortOrder.AUFSTEIGEND);
		System.out.println(Arrays.toString(arr));
		insertionSort(arr, SortOrder.ABSTEIGEND);
		System.out.println(Arrays.toString(arr));
	}
}

*seufz*

import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

public class InsertionSort
{

    public static void insertionSort(int[] a)
    {
        insertionSortAscending(a);
    }

    public static void insertionSortAscending(int[] a)
    {
        insertionSort(a, (x, y) -> -Integer.compare(x, y));
    }

    public static void insertionSortDescending(int[] a)
    {
        insertionSort(a, Integer::compare);
    }

    public static void insertionSort(int[] a,
        Comparator<Integer> comparator)
    {
        final int n = a.length;
        for (int j = 1; j < n; j++)
        {
            int key = a[j];
            int i = j - 1;
            while (i > -1 && comparator.compare(a[i], key) < 0)
            {
                a[i + 1] = a[i];
                i--;
            }
            a[i + 1] = key;
        }
    }

    public static void main(String[] args)
    {
        Random rd = new Random(1);
        int arr[] = new int[10];
        for (int i = 0; i < arr.length; i++)
        {
            arr[i] = rd.nextInt(100);
            System.out.println(arr[i]);
        }

        insertionSort(arr);
        System.out.println(Arrays.toString(arr));
        insertionSortDescending(arr);
        System.out.println(Arrays.toString(arr));
        insertionSortAscending(arr);
        System.out.println(Arrays.toString(arr));
        insertionSortDescending(arr);
        System.out.println(Arrays.toString(arr));
    }
}

Aber kein default parameter. :wink: :wink:

Und, soweit mit bekannt ist, sprechen die Engländer nur von natural oder non-natural (unnatural?) sort order.

Jaja, „*seufz*“ nicht zuletzt, weil ich schon mit so einem Scheiß gerechnet habe. Ja, es gibt keine default-Parameter in Java. Echt jetzt, sollen wir hier die nuts and bolts nochmal für dich durchkauen?

Aber angenommen, es gäbe eine magische, tolle, neue Sprache. Nennen wir sie mal „Jovo“. Die ist genau wie Java, hat aber default-Parameter. Das heißt, man kann schreiben

void doSomething(int value = 42) {
    System.out.println(value);
}

und die dann aufrufen:

doSomething(666); // Gibt 666 aus
doSomething(); // Gibt 42 aus

Wo wäre dann der Unterschied dazu, dass man in Java schreiben kann

void doSomething(int value) {
    System.out.println(value);
}
void doSomething() {
    doSomething(42);
}

Es ist syntaktisch und semantisch das gleiche. Default-Parameter sind überflüssig (und eher gefährlich).

Nicht ganz! In Java hat man beim Sortierenbeispiel einen Methodenaufruf mehr als in Jovo. :slight_smile:
(Durch das Delegieren)
Zudem ist der Wartungsaufwand in Java etwas höher, weil man bei einer Änderung alle Methoden anpacken muss…

Du verstehst doch, was ich meine?

Dann nimm Kotlin. Damit geht das.

Oder Python, Go, TypeScript, C# 4.0 oder c++… Es gibt quasi eine schiere Bandbreite an Sprachen, die das „dabei haben.“

Aber, verstehe mich nicht falsch, es hätte ja sein können, dass das ab Java 11 zum Beispiel dabei wäre. Jedes neue Feature bekomme ich auch nicht mit.

Der Unterschied von Kotlin ist, dass Du die Sprache einfach mit einer JVM nutzen kannst. Das geht mit Python, Go und co eben nicht. Java unterstützt dieses Feature jedenfalls nicht.

Yo, @Landei macht ja auch eine Menge mit Kotlin.

Obwohl ich dringend davon abrate, kann man in Java einen default-Parameter mittels vararg simulieren:

enum SortOrder {
   ASC,
   DESC
}

public static void insertionSort(int[] a,  SortOrder ... sos) {
   SortOrder sortOrder = sos.length == 0 ? ASC : sos[0];
   ...
}

Das käme bei mir aber nicht durchs Code-Review.

Wenn man wirklich will, kann man sich in solchen Fällen auch ein DSL schreiben:

sort(intArray).calc(); und sort(intArray).desc().calc()

Das ist hier nicht sehr sinnvoll, aber wenn man mehrere unabhängige Settings mit sinnvollen Defaults hätte, wäre es eine Überlegung wert.

Ab und zu mache ich Code-Reviews im akademischen Umfeld, und das käme bei mir auch nicht durchs Review; einfach, weil es das Potenzial birgt, Schindluder damit zu betreiben:

insertionSort(a, SortOrder.ASC, SortOrder.DESC, SortOrder.ASC);

Wer soll denn das verstehen?