我正在编写一个函数,它接受一个keyExtractor函数列表来生成一个Comparator(想象我们有一个具有许多属性的对象,并希望能够以任意顺序任意比较大量属性).
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
class Test {
public static <T, S extends Comparable<S>> Comparator<T> parseKeysAscending(List<Function<T, S>> keyExtractors) {
if (keyExtractors.isEmpty()) {
return (a, b) -> 0;
} else {
Function<T, S> firstSortKey = keyExtractors.get(0);
List<Function<T, S>> restOfSortKeys = keyExtractors.subList(1, keyExtractors.size());
return Comparator.comparing(firstSortKey).thenComparing(parseKeysAscending(restOfSortKeys));
}
}
public static void main(String[] args) {
List<Extractor<Data, ?>> extractors = new ArrayList<>();
extractors.add(new Extractor<>(Data::getA));
extractors.add(new Extractor<>(Data::getB));
Comparator<Data> test = parseKeysAscending(
extractors.stream()
.map(e -> e)
.collect(Collectors.toList()));
}
}
class Extractor<T, …Run Code Online (Sandbox Code Playgroud) 我有一个完整的ArrayList:
class TransitionState {
Position positionA;
Position positionB;
int counter;
public boolean equals (Object o){
if (o instanceof TransitionState){
TransitionState transitionState= (TransitionState)o;
if ((this.positionA.equals(transitionState.positionA))
&&(this.positionB.equals(transitionState.positionB)))
{
return true;
}
}
return false;
}
@Override
public String toString() {
String output = "Position A " + positionA.i+ " "+ positionA.j + " "+ positionA.orientation + " "+
"Position B " + positionB.i + " "+ positionB.j + " "+ positionB.orientation;
return output;
}
}
class Position {
int i;
int j; …Run Code Online (Sandbox Code Playgroud) 我有两个与我想要比较的相同类型对象的集合.在这种情况下,我想基于不考虑equals()对象的属性来比较它们.在我的例子中,我使用名称的排名集合,例如:
public class Name {
private String name;
private int weightedRank;
//getters & setters
@Override
public boolean equals(Object obj) {
return this.name.equals(obj.name); //Naive implementation just to show
//equals is based on the name field.
}
}
Run Code Online (Sandbox Code Playgroud)
我想比较两个集合来断言,对于i每个集合weightedRank中的位置,该位置的每个名称都是相同的值.我做了一些谷歌搜索,但没有在Commons Collections或任何其他API中找到合适的方法,所以我想出了以下内容:
public <T> boolean comparatorEquals(Collection<T> col1, Collection<T> col2,
Comparator<T> c)
{
if (col1 == null)
return col2 == null;
if (col2 == null)
return false;
if (col1.size() != col2.size())
return false;
Iterator<T> i1 = col1.iterator(), i2 …Run Code Online (Sandbox Code Playgroud) 在Java的类TreeSet文档中,其中一个构造函数显示为具有以下标题:
TreeSet(Comparator<? super E> c)
Run Code Online (Sandbox Code Playgroud)
有人可以帮助解释为什么TreeSet的构造函数将比较器对象作为其参数吗?我不知道为什么要这样做.
我想排序seq1升序和seq2降序所以我这样做:
list = list.stream().sorted(comparing(AClass::getSeq1).thenComparing(
AClass::getSeq2).reversed()).collect(toList());
Run Code Online (Sandbox Code Playgroud)
但结果出来了,因为seq1和seq2都按降序排序.
我可以这样做以使seq1升序和seq2降序:
sorted(comparing(AClass::getSeq1)
.reversed().thenComparing(AClass::getSeq2).reversed()
Run Code Online (Sandbox Code Playgroud)
这是真正的正确方法吗?
假设我有一个这样的域模型:
class Lecture {
Course course;
... // getters
}
class Course {
Teacher teacher;
int studentSize;
... // getters
}
class Teacher {
int age;
... // getters
}
Run Code Online (Sandbox Code Playgroud)
现在我可以像这样创建一个教师比较器:
return Comparator
.comparing(Teacher::getAge);
Run Code Online (Sandbox Code Playgroud)
但是,我如何比较Lecture的嵌套字段,像这样?
return Comparator
.comparing(Lecture::getCourse::getTeacher:getAge)
.thenComparing(Lecture::getCourse::getStudentSize);
Run Code Online (Sandbox Code Playgroud)
我无法Lecture.getTeacherAge()在模型上添加方法.
我有一类必须根据对象标识(即equals())定义相等性(按)。this == other
我想实现Comparable对此类对象进行排序(例如通过某些getName()属性)。要与其保持一致equals(),compareTo()不能返回0,即使两个对象具有相同的名称。
有没有一种在意义上比较对象身份的方法compareTo?我可以比较一下System.identityHashCode(o),但0在发生哈希冲突的情况下仍然可以返回。
从TreeMap的JavaDoc:
请注意,如果此有序映射要正确实现Map接口,则由有序映射维护的排序(无论是否提供显式比较器)必须与equals一致.(请参阅Comparable或Comparator以获得与equals一致的精确定义.)这是因为Map接口是根据equals操作定义的,但是map使用compareTo(或compare)方法执行所有键比较,因此有两个键从排序地图的角度来看,通过这种方法被视为相等的是相等的.即使排序与equals不一致,也可以很好地定义有序映射的行为.它只是不遵守Map接口的一般合同.
有人可以给出一个具体的例子来说明如果排序与equals不一致可能会出现的问题吗?举例来说,用户定义的类具有自然顺序,即它实现了Comparable.JDK中的所有内部类都保持这个不变量吗?
Parent是Child继承的类.这是由GrandChild继承的.每个类都包含子类的List(即Parent包含Child和Child的List包含GrandChild的List).每个类包含50个属性(attrib1-atrib50).getChildList()返回类型为Child的对象的arrayList getGrandChildList()返回GrandChild类型的对象的arrayList
设resultSet为Parent列表
List<Parent> resultSet
Run Code Online (Sandbox Code Playgroud)
现在我想根据一些属性对列表进行排序.例如,如果我想基于两个父属性(比如属性1和属性2)对resultSet进行排序,我使用此代码.
Comparator<Parent> byFirst = (e1, e2) -> e2.getAttrib1().compareTo(e1.getAttrib1());
Comparator<Parent> bySecond = (e1, e2) -> e1.getAttrib2().compareTo(e2.getAttrib2());
Comparator<Parent> byThird = byFirst.thenComparing(bySecond);
List<Parent> sortedList = resultSet.stream().sorted(byThird).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
现在我想根据Child类的属性1和GrandChild类的属性1对父列表进行排序.我应该如何排序呢.
我需要一些类implements Comparator,对于一个我想比较原始boolean(非Boolean)值.
如果它是一个B oolean,我会return boolA.compareTo(boolB);返回0,-1或1.但是我怎么能用原语做到这一点?
comparator ×10
java ×10
equals ×4
java-8 ×4
comparable ×3
collections ×2
generics ×2
java-stream ×2
sorting ×2
comparison ×1
lambda ×1
treeset ×1