将参数传递给枚举抽象方法
Passing argument to enum abstract method
我需要提供一个搜索属性工厂(作为 Strategy 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
的这些实现,但我不知道如何。
关于如何通过仍然使用 enum
很好地实现这一点的任何想法都会非常有帮助!
因为 Java 8,java.util.Comparator<T>
有一个默认方法 reversed()
可以使用。
你可以让你的 enum
实现 Comparator
,然后你得到反向排序 "for free",但这意味着改变 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;
}
}
那么,当您使用 class 实例时:
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
可能不是 "true" 比较器,而是 returns 比较器。这样你就可以更好地分离比较器实现的关注点:
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();
}
我需要提供一个搜索属性工厂(作为 Strategy 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
的这些实现,但我不知道如何。
关于如何通过仍然使用 enum
很好地实现这一点的任何想法都会非常有帮助!
因为 Java 8,java.util.Comparator<T>
有一个默认方法 reversed()
可以使用。
你可以让你的 enum
实现 Comparator
,然后你得到反向排序 "for free",但这意味着改变 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;
}
}
那么,当您使用 class 实例时:
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
可能不是 "true" 比较器,而是 returns 比较器。这样你就可以更好地分离比较器实现的关注点:
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();
}