-
Notifications
You must be signed in to change notification settings - Fork 0
/
Sort.java
executable file
·126 lines (102 loc) · 3.8 KB
/
Sort.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS info.picocli:picocli:4.6.2
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.Spec;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.Callable;
@Command(name = "Sort", mixinStandardHelpOptions = true, version = "Sort 0.1", description = "A sample sort program to illustrate Java stream and Array sort use")
class Sort implements Callable<Integer> {
@Spec
private CommandSpec commandSpec;
@Option(names = {"-i", "--ignore-case"}, description = "Enable ignore case")
private boolean ignoreCase;
@Option(names = {"-m", "--human-numeric-sort"}, description = "Enable human numeric sort")
private boolean humanNumericSort;
@Option(names = {"-n", "--numeric-sort"}, description = "Enable numeric sort")
private boolean numericSort;
@Option(names = {"-r", "--reverse"}, description = "Enable reverse sort")
private boolean reverse;
@Parameters(description = "Elements to sort")
private String[] elements;
public static void main(final String... args) {
int exitCode = new CommandLine(new Sort()).execute(args);
System.exit(exitCode);
}
@Override
public Integer call() {
if (elements == null) {
commandSpec.commandLine().usage(System.out);
return 1;
}
final Comparator comparator = reverse ? Comparator.reverseOrder() : Comparator.naturalOrder();
Arrays.stream(elements)
.map(element -> ignoreCase ? element.toUpperCase() : element)
.map(this::mapElement)
.sorted(comparator)
.forEach(element -> System.out.printf("%s ", element));
System.out.println();
return 0;
}
private Object mapElement(final String element) {
if (numericSort) {
return Double.parseDouble(element);
}
if (humanNumericSort) {
return HumanNumeric.parse(element);
}
return String.valueOf(element);
}
private enum Unit {
U(1),
k(1000 * U.size),
K(1000 * U.size),
M(1000 * K.size),
G(1000 * M.size),
T(1000 * G.size);
private final double size;
Unit(final double size) {
this.size = size;
}
@Override
public String toString() {
return this == U ? "" : name();
}
}
private static class HumanNumeric implements Comparable<HumanNumeric> {
private final double size;
private final Unit unit;
HumanNumeric(final double size, final Unit unit) {
this.size = size;
this.unit = unit;
}
public double getHumanSize() {
return size * unit.size;
}
public static HumanNumeric parse(final String element) {
final char lastChar = element.charAt(element.length() - 1);
if (Character.isDigit(lastChar)) {
return new HumanNumeric(Double.parseDouble(element), Unit.U);
}
for (final Unit unit : Unit.values()) {
if (element.endsWith(unit.name())) {
final String[] strings = element.split(unit.name());
return new HumanNumeric(Double.parseDouble(strings[0]), unit);
}
}
throw new IllegalArgumentException("Unknown unit: " + lastChar);
}
@Override
public int compareTo(final HumanNumeric human) {
return Double.compare(getHumanSize(), human.getHumanSize());
}
@Override
public String toString() {
return size + unit.toString();
}
}
}