#java #arrays
#java #массивы
Вопрос:
Итак, у меня есть класс на java, в котором я группирую переменные для создания моего объекта следующим образом:
public class ExampleClass
{
private String name;
private String test;
private int etc;
public ExampleClass()
{
}
public String getName()
{
return name;
}
public void setName(String newName)
{
name = newName;
}
// ...
}
Затем я создаю массив или список этих объектов, но для этого вопроса мы будем говорить массив:
int counter = 10;
ExampleClass e[] = new ExampleClass[counter];
for(int i = 0; i < counter; i )
{
ExampleClass e2 = ExampleClass();
e2.setName("a name"); // string grabbed from some other source...
// ...
e[i] = e2;
}
И затем я заполняю значения данными, которые могут быть любыми. Теперь мой вопрос в том, как я могу отсортировать свой массив (или список) по алфавитному порядку одной из переменных, например name
? Я использовал Arrays.sort(theArray)
раньше, когда это String[]
но я не совсем понимаю, как это сделать с моим пользовательским классом.
Просто отметим, что это все на java для Android, но платформа не должна иметь значения.
Ответ №1:
Вы можете создать компаратор для вашего ExampleClass и использовать SortedSet для хранения ваших объектов. Таким образом, ваши объекты всегда будут отсортированы. Например,
public class EComparator implements Comparator<ExampleClass> {
public int compare(ExampleClass o1, ExampleClas o2) {
return o1.getName().compareTo(o2.getName);
}
}
А затем используйте TreeSet для автоматической сортировки ваших примеров:
SortedSet<ExampleClass> data = new TreeSet<ExampleClass>(new EComparator());
data.add(e1);
data.add(e2);
data.add(e3);
data.add(e4);
Комментарии:
1. Вы можете преобразовать его в array или выполнить итерацию по нему.
2.
SortedSet
Просто гарантирует, что он будет перебирать свои элементы в указанном вами порядке. Таким образом, преобразование его в массив или захват итератора гарантируют порядок. Если вы это сделаетеnew ArrayList(mySet)
, это также будет работать.3. Сталкиваюсь с этим, но я чувствую, что использование
Comparable
интерфейса более объектно-ориентировано.4. Не уверен, что это более объектно-ориентированный. Единственное различие, которое я вижу, заключается в том, что, создавая несколько классов-компараторов, вы можете определить больше порядков сортировки, с Comparable вы можете определить только один порядок.
5. Спасибо, этот метод был первым из всех замечательных ответов, которые я получил здесь, работая. Мне понравилась идея ответа Вайнета, но я не смог заставить сортировку работать!
Ответ №2:
как я могу отсортировать свой массив (или список) по алфавитному порядку одной из переменных, такой как name?
Вам нужно, чтобы ваш класс реализовывал Comparable, или вам нужно предоставить пользовательский компаратор.
Bean Comparator показывает оба этих решения, а также предоставляет общее решение, поэтому вам не нужно каждый раз писать компараторы.
Комментарии:
1. 1 Это выглядит очень полезным. Еще не пробовал, так как у меня работает другой ответ, но спасибо, что дали мне знать.
Ответ №3:
Класс String реализует интерфейс Comparable, и именно поэтому строковые объекты в массиве могут быть отсортированы с помощью метода Arrays.sort.
Реализация сопоставимого интерфейса для вашего ExampleClass
класса снова позволит вам использовать Arrays.sort. Ниже приведен пример реализации, в котором сравниваются name
члены любых двух ExampleClass
экземпляров.
package com.example;
import java.util.Arrays;
public class ExampleClass implements Comparable<ExampleClass> {
private String name;
private String test;
private int etc;
public ExampleClass(String name, String test) {
this.name = name;
this.test = test;
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
/*
* This is where the comparison of instances occurs.
* The name of the argument is compared with the name of the current object.
* For the moment, the compareTo() method of the String class is used.
* But one could implement this without delegating to other classes,
* for other schemes of comparison to return a number.
*/
@Override
public int compareTo(ExampleClass o) {
return this.name.compareTo(o.getName());
}
@Override
public String toString() {
return "[" name "," test "]";
}
// ...
public static void main(String[] args) {
ExampleClass[] array = { new ExampleClass("B", "test1"),
new ExampleClass("A", "test1"), new ExampleClass("D", "test1"),
new ExampleClass("C", "test1"), new ExampleClass("E", "test1") };
Arrays.sort(array);
for(ExampleClass obj:array)
{
System.out.println(obj);
}
}
}
Комментарии:
1. Я думаю, это был бы самый простой ответ, но я не смог заставить его работать. Вы бы сделали это:
public class ExampleClass implements Comparator<ExampleClass>
?2. Хорошо, я опубликую пример кода. Попробуйте; не могу поручиться за его компиляцию, но это даст вам представление о том, как реализовать сопоставимый интерфейс.
Ответ №4:
Взгляните на Comparator или интерфейс Comparable.
По сути, каждый класс, который реализует Comparable, получает compareTo(…)-метод.
a.compareTo(b) вернет
Для случаев, когда вы не можете реализовать Comparable или не хотите этого делать, существует средство сравнения классов, которое может быть предоставлено методам сортировки по отдельности.
-1 if a<b
0 if a=b
and 1 if a>b
РЕДАКТИРОВАТЬ: Повозился с цитированием, теперь оно, по крайней мере, читабельно, если и не красиво : (
Ответ №5:
Здесь используется действительно грязный подход «из головы» —
Создайте Hashmap<String,ExampleClass>
где String будет обозначать строку, на основе которой вы хотели бы выполнить сортировку. Каждый раз, когда вы выполняете ‘setname’, добавляйте соответствующее сопоставление ключ-значение в HashMap.
Затем извлеките все ключи из этой хэш-карты и отсортируйте их (это будет простая сортировка строк). Теперь, когда у вас есть ключи в отсортированных значениях, переназначьте массив ‘e’ на основе отсортированного списка ключей.
Это должно привести к выполнению работы. Однако, сказав это, такой подход действительно заставляет меня съежиться 🙂