我有一个Vertex类,它具有通用类型T的字段元素。
我有一个Vertex对象的ArrayList,我想对其进行排序,但是我不确定如何。
我尝试使用比较器,如下所示:
listOfNeighbours.sort(new Comparator<Vertex<T>>() {
@Override
public int compare(Vertex<T> v1, Vertex<T> v2) {
if(v1.getElement() == v2.getElement()){
return 0;
}else if(v1.getElement() < v2.getElement()) {
return -1;
}else {
return 1;
}
}
});
显然,上述解决方案是错误的,因为我们无法比较泛型,但我希望与此类似的东西可以对我的Vertex对象列表进行排序。
在我的应用程序中,T可以是整数,双精度或字符串。
感谢您的帮助!
谢谢。
编辑:我的Vertex类在下面:
public class Vertex<T>{
private ObjectProperty<T> element;
private BooleanProperty visited;
public Vertex() {
element = null;
visited = new SimpleBooleanProperty(false);
}
public Vertex(T element) {
this.element = new SimpleObjectProperty<T>(element);
this.visited = new SimpleBooleanProperty(false);
}
public Vertex(T element, boolean visited) {
this.element = new SimpleObjectProperty<T>(element);
this.visited = new SimpleBooleanProperty(visited);
}
public void setElement(T elem) {
this.element.set(elem);
}
public T getElement() {
return this.element.get();
}
public ObjectProperty<T> elementProperty(){
return this.element;
}
public void setVisited(boolean b) {
this.visited.set(b);
}
public boolean isVisited() {
return this.visited.get();
}
public BooleanProperty visitedProperty(){
return this.visited;
}
@Override
public boolean equals(Object o) {
if(o == this) {
return true;
}
if(!(o instanceof Vertex<?>)) {
return false;
}
Vertex<?> v= (Vertex<?>) o;
if(v.getElement() instanceof String) {
return v.getElement().equals(this.element.get());
}else {
return v.getElement() == this.element.get();
}
}
@Override
public String toString() {
return element.get().toString();
}
}
答案 0 :(得分:4)
Comparator是件好事。对于此特定问题,它具有static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)
。就您而言,应该是
listOfNeighbours.sort(Comparator.comparing(Vertex::getElement))
如果您的Vertex组件不是Comparable
,我建议您改用static <T,U> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator)
,它可以与自定义比较器一起使用。
例如,
import java.util.*;
import javafx.beans.property.*;
public class Vertex<T>{
private ObjectProperty<T> element;
private BooleanProperty visited;
public Vertex() {
element = null;
visited = new SimpleBooleanProperty(false);
}
public Vertex(T element) {
this.element = new SimpleObjectProperty<T>(element);
this.visited = new SimpleBooleanProperty(false);
}
public Vertex(T element, boolean visited) {
this.element = new SimpleObjectProperty<T>(element);
this.visited = new SimpleBooleanProperty(visited);
}
public void setElement(T elem) {
this.element.set(elem);
}
public T getElement() {
return this.element.get();
}
public ObjectProperty<T> elementProperty(){
return this.element;
}
public void setVisited(boolean b) {
this.visited.set(b);
}
public boolean isVisited() {
return this.visited.get();
}
public BooleanProperty visitedProperty(){
return this.visited;
}
@Override
public boolean equals(Object o) {
if(o == this) {
return true;
}
if(!(o instanceof Vertex<?>)) {
return false;
}
Vertex<?> v= (Vertex<?>) o;
if(v.getElement() instanceof String) {
return v.getElement().equals(this.element.get());
}else {
return v.getElement() == this.element.get();
}
}
@Override
public String toString() {
return element.get().toString();
}
public static void main(String[] args) {
ArrayList<Vertex<String>> listOfNeighbours = new ArrayList<>();
listOfNeighbours.add(new Vertex<>("foo"));
listOfNeighbours.add(new Vertex<>("bar"));
System.out.println(listOfNeighbours);
listOfNeighbours.sort(Comparator.comparing(Vertex::getElement));
System.out.println(listOfNeighbours);
ArrayList<Vertex<Integer>> list2 = new ArrayList<>();
list2.add(new Vertex<>(1));
list2.add(new Vertex<>(123));
list2.add(new Vertex<>(15));
list2.add(new Vertex<>(2));
System.out.println(list2);
list2.sort(Comparator.comparing(Vertex::getElement));
System.out.println(list2);
list2.sort(Comparator.comparing(Vertex::getElement, Comparator.comparing(i -> i.toString())));
System.out.println(list2);
}
}
将如何完成(用https://www.compilejava.net/测试)。
结果是
[foo, bar]
(原始输入)
[bar, foo]
(按字符串排序)
[1, 123, 15, 2]
(原始输入)
[1, 2, 15, 123]
(按整数自然顺序排序)
[1, 123, 15, 2]
(按给定的字符串顺序,即从字法上来说)。
后者是通过Comparator<Vertex<Integer>>
完成的,它通过提取给定Vertex<Integer>
的值并将其转换为String
(然后用作排序键)来完成其工作。
答案 1 :(得分:1)
如果将T限制为Comparable<? super T>
,则上述@glglgl解决方案就足够了,因为似乎T
可能基于该问题采用的任何类型都符合要求。
但是,如果T
不受此限制,并且您不能或不想更改它,则解决方案会更通用一些,并且要求调用代码为{{ 1}}元素作为T
Comparator.comparing
您无需为此定义单独的(静态)方法,如果愿意,可以内联。
对于元素类型类似于static <T> void sortNeightbours(Collection<Vertex<? extends T>> neighbours, Comparator<? super T> elementComparator) {
neighbours.sort(Comparator.comparing(Vertex::getElement, elementComparator);
}
,Integer
或Double
的顶点,调用代码将相同:
String
您可以定义其他方法来处理Comparables,这样就不必每次都在代码中添加 List<Vertex<Integer>> ints = ...;
List<Vertex<Double>> dbls = ...;
List<Vertex<String>> strs = ...;
sortNeighbours(ints, Comparator.naturalOrder());
sortNeighbours(dbls, Comparator.naturalOrder());
sortNeighbours(strs, Comparator.naturalOrder());
调用。
答案 2 :(得分:0)
问题是,您想进行比较时是否知道顶点中的元素类型。
即由于类型擦除,此代码有效:
Vertex<String> strVtx = ...
Vertex<Integer> intVtx = ...
List<Vertex> list = Arrays.asList(strVtx, intVtx);
list.sort(aComparer);
因此,这里的比较器实现很困难。
但是,如果您知道类型,就可以轻松做到:
List<Vertex<Integer>> list = ...
list.sort(Comparator.comparing(Vertex::getElement);