Java 函数解代替迭代解
我必须执行以下任务。为了简单起见,我创建了下表: 我们有输入和一个定义了规则的表。如果有任何规则与此输入匹配,则对其应用操作 例如,输入Java 函数解代替迭代解,java,java-8,functional-programming,Java,Java 8,Functional Programming,我必须执行以下任务。为了简单起见,我创建了下表: 我们有输入和一个定义了规则的表。如果有任何规则与此输入匹配,则对其应用操作 例如,输入HBC1234: 以H=>true开始 因此,将匹配的_值(H)替换为M=>结果是MBC1234 以相同的方式迭代此输入的所有其他规则 以下是替换规则的实体: @Data @Entity @NoArgsConstructor public class ReplacementRule implements Serializable { private s
HBC1234
:
M
=>结果是MBC1234
@Data
@Entity
@NoArgsConstructor
public class ReplacementRule implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@NotNull
@Enumerated(EnumType.STRING)
private MatchingOperation matchingOperation;
@NotNull
private String matchingValue;
@NotNull
@Enumerated(EnumType.STRING)
private ReplacementOperation replacementOperation;
private String replacementValue;
}
这项任务的执行情况:
private static String apply(ReplacementRule rule, String plateNumber) {
switch (rule.getMatchingOperation()) {
case STARTS_WITH:
if (plateNumber.startsWith(rule.getMatchingValue())) {
return switch (rule.getReplacementOperation()) {
case REPLACE -> plateNumber.replaceFirst(rule.getMatchingValue(), rule.getReplacementValue());
case REMOVE -> plateNumber.substring(rule.getMatchingValue().length());
};
}
case CONTAINS:
if (plateNumber.contains(rule.getMatchingValue())) {
return switch (rule.getReplacementOperation()) {
case REPLACE -> plateNumber.replaceAll(rule.getMatchingValue(), rule.getReplacementValue());
case REMOVE -> plateNumber.replaceAll(rule.getMatchingValue(), "");
};
}
case ENDS_WITH:
if (plateNumber.endsWith(rule.getMatchingValue())) {
return switch (rule.getReplacementOperation()) {
case REPLACE -> plateNumber.substring(0, getEndIndex(rule, plateNumber)).concat(rule.getReplacementValue());
case REMOVE -> plateNumber.substring(0, getEndIndex(rule, plateNumber));
};
}
case EQUALS:
if (plateNumber.equals(rule.getMatchingValue())) {
return switch (rule.getReplacementOperation()) {
case REPLACE -> rule.getReplacementValue();
case REMOVE -> "";
};
}
}
return "";
}
private static int getEndIndex(ReplacementRule rule, String plateNumber) {
return plateNumber.length() - rule.getMatchingValue().length();
}
最终用法如下所示:
public Optional<WhiteList> checkReplacementRules(String plateNumber) {
List<ReplacementRule> allRules = ruleRepository.findAll();
Optional<WhiteList> result = Optional.empty();
for (ReplacementRule rule : allRules) {
String newPlate = transform(rule, plateNumber);
if (StringUtils.isNotBlank(newPlate)) {
result = whiteListRepository.findByNumberPlate(newPlate);
}
}
return result;
}
public可选checkReplacementRules(字符串编号){
List allRules=ruleRepository.findAll();
可选结果=可选。空();
for(替换规则:所有规则){
字符串newPlate=变换(规则、板材编号);
如果(StringUtils.isNotBlank(newPlate)){
结果=whiteListRepository.findByNumberPlate(newPlate);
}
}
返回结果;
}
它将匹配和逻辑结合起来,在一个方法中进行替换apply()
。然而,它违反了法律。但它是有效的。尽管这个解决方案不是最好的
这种任务似乎与函数式编程概念相匹配
如何将其重新设计为功能性风格
Java版本是15让
enum
类实现操作,即操作
正则表达式似乎非常适合你所做的事情
私有静态字符串应用(替换规则,字符串编号){
字符串regex=rule.getMatchingOperation().regexFor(rule.getMatchingValue());
字符串替换=rule.getReplacementOperation().regexFor(rule.getReplacementValue());
返回模式.compile(regex)
.匹配器(板号)
.replaceFirst(替换);
}
公共枚举匹配操作{
以(v->“^”+模式开头。引号(v)),
包含(v->Pattern.quote(v)),
以(v->Pattern.quote(v)+“$”)结束,
等于(v->“^”+模式。引号(v)+“$”;
私人最终一元运算符asRegex;
专用匹配操作(UnaryOperator asRegex){
this.asRegex=asRegex;
}
公共字符串regexFor(字符串匹配值){
返回此.asRegex.apply(匹配值);
}
}
公共枚举替换操作{
替换(匹配器::引用替换),
移除(v->”);
私人最终一元运算符asRegex;
专用替换操作(UnaryOperator asRegex){
this.asRegex=asRegex;
}
公共字符串regexFor(字符串替换值){
返回此.asRegex.apply(replacementValue);
}
}
让enum
类实现操作,即操作
正则表达式似乎非常适合你所做的事情
私有静态字符串应用(替换规则,字符串编号){
字符串regex=rule.getMatchingOperation().regexFor(rule.getMatchingValue());
字符串替换=rule.getReplacementOperation().regexFor(rule.getReplacementValue());
返回模式.compile(regex)
.匹配器(板号)
.replaceFirst(替换);
}
公共枚举匹配操作{
以(v->“^”+模式开头。引号(v)),
包含(v->Pattern.quote(v)),
以(v->Pattern.quote(v)+“$”)结束,
等于(v->“^”+模式。引号(v)+“$”;
私人最终一元运算符asRegex;
专用匹配操作(UnaryOperator asRegex){
this.asRegex=asRegex;
}
公共字符串regexFor(字符串匹配值){
返回此.asRegex.apply(匹配值);
}
}
公共枚举替换操作{
替换(匹配器::引用替换),
移除(v->”);
私人最终一元运算符asRegex;
专用替换操作(UnaryOperator asRegex){
this.asRegex=asRegex;
}
公共字符串regexFor(字符串替换值){
返回此.asRegex.apply(replacementValue);
}
}
我不认为您的设计违反了开闭原则,但是,下面是我的实现。由于它可以将未来的需求添加为功能,因此可以称为功能性需求
@FunctionalInterface
interface Rule {
public String apply(String string);
}
规则
适用于每个需求的功能
class Replacement {
ArrayList<Rule> rules = new ArrayList<Rule>();
public Replacement addRule(Rule rule) {
rules.add(rule);
return this;
}
public String applyAll(String string) {
System.out.printf("%s --> ", string);
for (Rule rule : rules) {
string = rule.apply(string);
}
System.out.println(string);
return string;
}
}
我不认为您的设计违反了开闭原则,但是,下面是我的实现。由于它可以将未来的需求添加为功能,因此可以称为功能性需求
@FunctionalInterface
interface Rule {
public String apply(String string);
}
规则
适用于每个需求的功能
class Replacement {
ArrayList<Rule> rules = new ArrayList<Rule>();
public Replacement addRule(Rule rule) {
rules.add(rule);
return this;
}
public String applyAll(String string) {
System.out.printf("%s --> ", string);
for (Rule rule : rules) {
string = rule.apply(string);
}
System.out.println(string);
return string;
}
}
为什么你认为它违反了开放-封闭原则<代码> >案例< /代码> S将被添加吗?将来添加哪些需求/条件总是不可预测的。如果添加了新的需求,是否可以避免更改代码?我认为您的代码可以始终如一地添加规则并满足需求。“替换操作”的抽象真的有必要吗?删除和删除之间没有区别“用一个空字符串替换”,字符串无论如何都被携带。“霍格尔好,为什么你认为它违反了开放的封闭原理?”代码>用例< /代码> S将会被添加吗?[可预测未来将添加哪些需求/条件。如果添加新的需求,是否可以避免更改代码?我认为您的代码可以始终添加规则并满足需求。“替换操作”的抽象真的有必要吗?删除和删除之间没有区别“替换为空字符串”并且字符串仍然被携带。@Holger good Shot不使用
UnaryOperator
和Pattern.compile
在类外,使用函数
更有意义。然后可以使用Pattern.compile(v,Pattern.LITERAL)
for包含
。最好包含实际匹配的op