У меня есть и массив типа Object [], содержащий целые числа и строки (одиночные буквы).
Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};
Каков мой вопрос, есть ли простой способ отсортировать этот массив, прежде всего, с помощью ints перед строками, а во-вторых, с помощью ints в числовом порядке возрастания и строки в алфавитном порядке? Я искал нечто похожее на метод Arrays.sort, но я не думаю, что все будет так просто.
спасибо
Один из способов - предоставить экземпляр Comparator<Object>
и проверить тип объектов, чтобы определить их сортировку:
Arrays.sort(myArray, new IntStringComparator());
//...
public static class IntStringComparator implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
if (o1 == null) {
return -1; // o1 is null, should be less than any value
}
if(o2 == null){
return 1; // o2 is null, should be less than any non-null value
}
if (o1 instanceof Integer) {
if (o2 instanceof Integer) {
return Integer.compare((int) o1, (int) o2); // Compare by int
} else {
return -1; // int < String
}
} else {
if (o2 instanceof String) {
return ((String) o1).compareTo((String) o2); // Compare by string
} else {
return 1; // String > int
}
}
}
}
Выходы:
[2, 4, U, U, U, X]
В Java 8:
Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};
Stream.of(myArray).filter(x -> !(x instanceof String))
.sorted().forEach(System.out::print);
Stream.of(myArray).filter(x -> x instanceof String)
.sorted().forEach(System.out::print);
Для Дэвида Уоллеса: если вы хотите сохранить отсортированный массив (я сохраняю его в списке в этом примере, но его можно преобразовать в .toArray()
если вы хотите):
Object[] myArray = {(String) "U", (String) "U", (int) 2, (String) "X", (int) 4, (String) "U"};
List<Object> newList = Stream.of(myArray).filter(x -> x instanceof String)
.sorted().collect(Collectors.toList());
Collections.addAll(newList, Stream.of(myArray).filter(x -> !(x instanceof String))
.sorted().toArray());
for (Object o : newList) {
System.out.print(o);
}
OUTPUT (обоих фрагментов кода):
24UUUX
Тем не менее, это плохая практика, чтобы смешивать разные типы в одном массиве (использовать Object
как и вы). Различные типы должны быть "смешанными", только если они имеют общий интерфейс (или, если один из них расширяет другой)!
int
s перед String
s в выводе.
Я думаю, что лучший способ - создать Generic Class, который будет реализовывать интерфейс Comparable. Таким образом, вы можете хранить любой тип в массиве и иметь метод сравнения, чтобы делать то, что вы хотите.
Вы можете указать функцию, используемую для сравнения объектов, и, таким образом, заставить ее вести себя, как вам нравится. Например, см. Java. Как я могу наиболее эффективно сортировать массив объектов SomeClass по полю String в этих объектах?