BAEL-6822: Difference between Arrays.sort() and Collections.sort() (#14787)
This commit is contained in:
parent
d6db7fd6e7
commit
1e7471a2b3
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
import com.baeldung.collectionsvsarrays.sorting.Quicksort;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NonStableSortExample {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
List<Task> tasks = Tasks.supplier.get();
|
||||||
|
Quicksort.sort(tasks, Comparator.comparingInt(Task::getPriority));
|
||||||
|
System.out.println("After sorting by priority:");
|
||||||
|
for (Task task : tasks) {
|
||||||
|
System.out.println(task);
|
||||||
|
}
|
||||||
|
Quicksort.sort(tasks, Comparator.comparing(Task::getDueDate));
|
||||||
|
System.out.println("\nAfter sorting by due date:");
|
||||||
|
for (Task task : tasks) {
|
||||||
|
System.out.println(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
|
@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.MINUTES)
|
||||||
|
@Warmup(iterations = 5, time = 10)
|
||||||
|
@Fork(value = 2)
|
||||||
|
public class ObjectOverheadBenchmark {
|
||||||
|
|
||||||
|
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public static class Input {
|
||||||
|
public Supplier<List<Integer>> randomNumbers = () -> RANDOM.ints().limit(10000).boxed().collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
public void sortingPrimitiveArray(Input input, Blackhole blackhole) {
|
||||||
|
final int[] array = input.randomNumbers.get().stream().mapToInt(Integer::intValue).toArray();
|
||||||
|
Arrays.sort(array);
|
||||||
|
final List<Integer> result = Arrays.stream(array).boxed().collect(Collectors.toList());
|
||||||
|
blackhole.consume(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
public void sortingObjectArray(Input input, Blackhole blackhole) {
|
||||||
|
final Integer[] array = input.randomNumbers.get().toArray(new Integer[0]);
|
||||||
|
Arrays.sort(array);
|
||||||
|
blackhole.consume(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
public void sortingObjects(Input input, Blackhole blackhole) {
|
||||||
|
final List<Integer> list = input.randomNumbers.get();
|
||||||
|
Collections.sort(list);
|
||||||
|
blackhole.consume(list);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
import com.baeldung.collectionsvsarrays.sorting.MergeSort;
|
||||||
|
import com.baeldung.collectionsvsarrays.sorting.Quicksort;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
|
||||||
|
@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.MINUTES)
|
||||||
|
@Warmup(iterations = 5, time = 10)
|
||||||
|
public class PerformanceBenchmark {
|
||||||
|
|
||||||
|
private static final Random RANDOM = new Random();
|
||||||
|
private static final int ARRAY_SIZE = 10000;
|
||||||
|
private static final int[] randomNumbers = RANDOM.ints(ARRAY_SIZE).toArray();
|
||||||
|
private static final int[] sameNumbers = IntStream.generate(() -> 42).limit(ARRAY_SIZE).toArray();
|
||||||
|
public static final Supplier<int[]> randomNumbersSupplier = randomNumbers::clone;
|
||||||
|
public static final Supplier<int[]> sameNumbersSupplier = sameNumbers::clone;
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-quick-sort-same-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
|
||||||
|
public void quickSortSameNumber() {
|
||||||
|
Quicksort.sort(sameNumbersSupplier.get());
|
||||||
|
}
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-quick-sort-random-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
|
||||||
|
public void quickSortRandomNumber() {
|
||||||
|
Quicksort.sort(randomNumbersSupplier.get());
|
||||||
|
}
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-merge-sort-same-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
|
||||||
|
public void mergeSortSameNumber() {
|
||||||
|
MergeSort.sort(sameNumbersSupplier.get());
|
||||||
|
}
|
||||||
|
@Benchmark
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, jvmArgs = {"-Xlog:gc:file=gc-logs-merge-sort-random-number-%t.txt,filesize=900m -Xmx6gb -Xms6gb"})
|
||||||
|
public void mergeSortRandomNumber() {
|
||||||
|
MergeSort.sort(randomNumbersSupplier.get());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StableSortExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final List<Task> tasks = Tasks.supplier.get();
|
||||||
|
Collections.sort(tasks, Comparator.comparingInt(Task::getPriority));
|
||||||
|
System.out.println("After sorting by priority:");
|
||||||
|
for (Task task : tasks) {
|
||||||
|
System.out.println(task);
|
||||||
|
}
|
||||||
|
Collections.sort(tasks, Comparator.comparing(Task::getDueDate));
|
||||||
|
System.out.println("\nAfter sorting by due date:");
|
||||||
|
for (Task task : tasks) {
|
||||||
|
System.out.println(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
public class Task {
|
||||||
|
private final long id;
|
||||||
|
private final int priority;
|
||||||
|
private final String dueDate;
|
||||||
|
|
||||||
|
public Task(final long id, int priority, String dueDate) {
|
||||||
|
this.id = id;
|
||||||
|
this.priority = priority;
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("Task: #%-2d | Priority: %d | Due Date: %s", getId(), getPriority(), getDueDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPriority() {
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDueDate() {
|
||||||
|
return dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.collectionsvsarrays;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class Tasks {
|
||||||
|
|
||||||
|
private static final List<Task> tasks;
|
||||||
|
public static final Supplier<List<Task>> supplier;
|
||||||
|
|
||||||
|
static {
|
||||||
|
tasks = new ArrayList<>();
|
||||||
|
tasks.add(new Task(1, 1, "2023-09-01"));
|
||||||
|
tasks.add(new Task(2, 2, "2023-08-30"));
|
||||||
|
tasks.add(new Task(3, 1, "2023-08-29"));
|
||||||
|
tasks.add(new Task(4, 2, "2023-09-02"));
|
||||||
|
tasks.add(new Task(5, 3, "2023-09-05"));
|
||||||
|
tasks.add(new Task(6, 1, "2023-09-03"));
|
||||||
|
tasks.add(new Task(7, 3, "2023-08-28"));
|
||||||
|
tasks.add(new Task(8, 2, "2023-09-01"));
|
||||||
|
tasks.add(new Task(9, 1, "2023-08-28"));
|
||||||
|
tasks.add(new Task(10, 2, "2023-09-04"));
|
||||||
|
tasks.add(new Task(11, 3, "2023-08-31"));
|
||||||
|
tasks.add(new Task(12, 1, "2023-08-30"));
|
||||||
|
tasks.add(new Task(13, 3, "2023-09-02"));
|
||||||
|
|
||||||
|
supplier = () -> new ArrayList<>(tasks);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.collectionsvsarrays.sorting;
|
||||||
|
|
||||||
|
public class MergeSort {
|
||||||
|
|
||||||
|
public static void sort(int[] a) {
|
||||||
|
sort(a, a.length);
|
||||||
|
}
|
||||||
|
public static void sort(int[] a, int n) {
|
||||||
|
if (n < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int mid = n / 2;
|
||||||
|
int[] l = new int[mid];
|
||||||
|
int[] r = new int[n - mid];
|
||||||
|
|
||||||
|
for (int i = 0; i < mid; i++) {
|
||||||
|
l[i] = a[i];
|
||||||
|
}
|
||||||
|
for (int i = mid; i < n; i++) {
|
||||||
|
r[i - mid] = a[i];
|
||||||
|
}
|
||||||
|
sort(l, mid);
|
||||||
|
sort(r, n - mid);
|
||||||
|
|
||||||
|
merge(a, l, r, mid, n - mid);
|
||||||
|
}
|
||||||
|
private static void merge(
|
||||||
|
int[] a, int[] l, int[] r, int left, int right) {
|
||||||
|
|
||||||
|
int i = 0, j = 0, k = 0;
|
||||||
|
while (i < left && j < right) {
|
||||||
|
if (l[i] <= r[j]) {
|
||||||
|
a[k++] = l[i++];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a[k++] = r[j++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < left) {
|
||||||
|
a[k++] = l[i++];
|
||||||
|
}
|
||||||
|
while (j < right) {
|
||||||
|
a[k++] = r[j++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.baeldung.collectionsvsarrays.sorting;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Quicksort {
|
||||||
|
|
||||||
|
public static void sort(int arr[]) {
|
||||||
|
sort(arr, 0, arr.length - 1);
|
||||||
|
}
|
||||||
|
public static void sort(int arr[], int begin, int end) {
|
||||||
|
if (begin < end) {
|
||||||
|
int partitionIndex = partition(arr, begin, end);
|
||||||
|
|
||||||
|
sort(arr, begin, partitionIndex-1);
|
||||||
|
sort(arr, partitionIndex+1, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static int partition(int arr[], int begin, int end) {
|
||||||
|
int pivot = arr[end];
|
||||||
|
int i = (begin-1);
|
||||||
|
|
||||||
|
for (int j = begin; j < end; j++) {
|
||||||
|
if (arr[j] <= pivot) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
int swapTemp = arr[i];
|
||||||
|
arr[i] = arr[j];
|
||||||
|
arr[j] = swapTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int swapTemp = arr[i+1];
|
||||||
|
arr[i+1] = arr[end];
|
||||||
|
arr[end] = swapTemp;
|
||||||
|
|
||||||
|
return i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void sort(List<T> list, Comparator<T> comparator) {
|
||||||
|
sort(list, 0, list.size() - 1, comparator);
|
||||||
|
}
|
||||||
|
public static <T> void sort(List<T> list, int low, int high, Comparator<T> comparator) {
|
||||||
|
if (low < high) {
|
||||||
|
int partitionIndex = partition(list, low, high, comparator);
|
||||||
|
|
||||||
|
sort(list, low, partitionIndex - 1, comparator);
|
||||||
|
sort(list, partitionIndex + 1, high, comparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> int partition(List<T> list, int begin, int end, Comparator<T> comparator) {
|
||||||
|
T pivot = list.get(end);
|
||||||
|
int i = (begin-1);
|
||||||
|
|
||||||
|
for (int j = begin; j < end; j++) {
|
||||||
|
if (comparator.compare(list.get(j), pivot) <= 0) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
T swapTemp = list.get(i);
|
||||||
|
list.set(i, list.get(j));
|
||||||
|
list.set(j, swapTemp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T swapTemp = list.get(i+1);
|
||||||
|
list.set(i+1,list.get(end));
|
||||||
|
list.set(end, swapTemp);
|
||||||
|
|
||||||
|
return i+1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue