我需要提供一个搜索属性工厂(作为策略 OOP 原则的一部分)。 我为选择编写了以下枚举:
public enum CompareChoice {
ABS {
public Path compare(Path path1, Path path2) {
return absCompare(path1, path2);
}
},
TYPE {
public Path compare(Path path1, Path path2) {
String type1 = getFileType(path1);
String type2 = getFileType(path2);
int compareValue = type1.compareTo(type2);
if (compareValue == 0) {
return absCompare(path1, path2);
}
if (compareValue > 0) {
return path1;
}
return path2;
}
},
SIZE {
public Path compare(Path path1, Path path2) throws IOException {
Long size1 = Files.size(path1);
Long size2 = Files.size(path2);
int compareValue = size1.compareTo(size2);
if (compareValue == 0) {
return absCompare(path1, path2);
}
if (compareValue > 0) {
return path1;
}
return path2;
}
};
public abstract Path compare(Path path1, Path path2) throws IOException;
}
我面临的问题是我需要支持反向排序(所有三个选择)。
我想以某种方式将 boolean
参数传递给 compare
的这些实现,但我不知道如何实现。
任何关于如何通过仍然使用枚举
来很好地实现这一点的想法都会非常有帮助!
最佳答案
自 Java 8 起,java.util.Comparator<T>
有一个默认方法 reversed()
您可以使用。
您可以将您的enum
实现Comparator
,然后你“免费”获得反向排序,但这意味着更改 compare
的签名适合Comparator
合约(您需要为该方法想出另一个名称,在我的示例中,我将其命名为 select
;
仅采用一个枚举值以保持简短:
public enum CompareChoice implements Comparator<Path> {
SIZE {
@Override
public int compare(Path path1, Path path2) {
int r = Long.compare(
Files.size(path1),
Files.size(path2)
);
if (r == 0) {
return absCompare(path1, path2);
}
else {
return r;
}
}
};
// rest of the methods:
public static Path select(Comparator<? super Path> rule, Path path1, Path path2) {
return rule.compare(path1, path2) <= 0 ? path1 : path2;
}
}
那么,当您使用类实例时:
CompareChoice choice = CompareChoice.SIZE;
Path path1 = fileOfSize(1, TB);
Path path2 = fileOfSize(3, TB);
Path naturalOrderResult = CompareChoice.select(choice, path1, path2);
Path reversedOrderResult = CompareChoice.select(choice.reversed(), path1, path2);
assert path1 == naturalOrderResult;
assert path2 == reversedOrderResult;
您可以查看比较器中的其他默认方法,以检查您还可以从实现 Comparator<T>
中获得的其他内容,尽管其中大部分可能对您没有多大用处。
您也可以考虑将其作为一个整体进行重构,因此您的 CompareChoice
可能不是“真正的”比较器,而是返回一个比较器。这样您就可以更好地分离比较器实现的关注点:
public enum CompareChoice {
ABS {
public Comparator<? extends Path> comparator() {
return Comparator.comparing(this::absCompare); // whatever absCompare means
}
},
SIZE {
public Comparator<? extends Path> comparator() {
return Comparator.comparingLong(Files::size).thenComparing(ABS.comparator());
}
};
public abstract Comparator<? extends Path> comparator();
}
关于java - 将参数传递给枚举抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59518846/