java - 将参数传递给枚举抽象方法

标签 java oop enums factory

我需要提供一个搜索属性工厂(作为策略 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/

相关文章:

java - CordApp Java 堆空间错误和 javax.net.ssl.SSLException

java - 将 EditText 值转换为 int

.net - 与DataGridColumn.Visibility匹配的F#模式

objective-c - Objective-C - "typedef"什么时候应该在 "enum"之前,什么时候应该命名枚举?

java - SQL查询语法错误

java - GWT:如何在 UiBinder 模板中使用常量

javascript - AngularJS 工厂对象被引用

C# 编译器忽略构造函数中重复的参数名称

Equals() 的 C++ 双重分派(dispatch)

c# - 在 asp.net 中保留枚举值