Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中对DRY原则的违反_Java_Dry - Fatal编程技术网

Java中对DRY原则的违反

Java中对DRY原则的违反,java,dry,Java,Dry,我有三种方法可以按字段过滤设备数组 public void filtrateByType(Device[] devices, String type) { if (devices == null) { return; } for (int i = 0; i < devices.length; i++) { if (devices[i] == null) { continue; }

我有三种方法可以按字段过滤设备数组

public void filtrateByType(Device[] devices, String type) {
    if (devices == null) {
        return;
    }

    for (int i = 0; i < devices.length; i++) {
        if (devices[i] == null) {
            continue;
        }

        if (devices[i].getType() == null && type == null) {
            continue;
        } else if (devices[i].getType() == null) {
            devices[i] = null;
            continue;
        }

        if (!devices[i].getType().equals(type)) {
            devices[i] = null;
        }
    }
}
public void filterbytype(设备[]设备,字符串类型){
如果(设备==null){
返回;
}
对于(int i=0;i
其他方法也类似。唯一的区别是调用应用过滤的字段的另一个getter。例如,调用了
getModel()
,而不是
getType()
。这是否违反了DRY原则?我如何更改它,使其不会(没有泛型)

p.S.
这是一个家庭作业,不幸的是我们还没有使用泛型。我也不能更改方法的签名。我有一个线索,我可以用一个方法创建内部类,该方法将调用所需的getter并返回一个值。因此,我需要将所有检查都放在这个方法中,但我真的不明白如何使用我的逻辑(尤其是“continue”)。

也许一些Java 8魔术会有帮助:

public void filtrateByType(Device[] devices, String type) {
    filtrateBy(devices, Device::getType, type);
}

public void filtrateBy(Device[] devices, Function<? super Device, String> attributeGetter, String attribute) {
    if (devices == null) {
        return;
    }
    for (int i = 0; i < devices.length; i++) {

        if (devices[i] == null) {
            continue;
        }

        if (attributeGetter.apply(devices[i]) == null && attribute == null) {
            continue;
        } else if (attributeGetter.apply(devices[i]) == null) {
            devices[i] = null;
            continue;
        }
        if (!attributeGetter.apply(devices[i]).equals(attribute)) {
            devices[i] = null;
        }
    }
}
public void filterbytype(设备[]设备,字符串类型){
过滤比(设备,设备::getType,type);
}

public void filterBy(设备[]设备,函数您可以创建一个
接口设备值提取器
,如下所示:

@FunctionalInterface
public interface DeviceValueExtractor {
    Object extractValue(Device device);
}
现在将您的方法重写为:

public void filterByType(Device[] devices, DeviceValueExtractor extractor, Object expect) {
    if (devices == null) {
        return;
    }
    for (int i = 0; i < devices.length; i++) {
        if (devices[i] == null) {
            continue;
        }
        Object actual = extractor.extractValue(devices[i]);
        if (actual == null && expect== null) {
            continue;
        } else if (actual  == null) {
            devices[i] = null;
            continue;
        }
        if (!Objects.equals(actual, expect)) {
            devices[i] = null;
        }
    }
 }

注意:我使用了
对象
,因为不需要泛型-因为唯一调用的方法是
等于
,这其实没什么大不了的

但是,为了更大的类型安全性,您可以引入泛型(并取消
DeviceValueExtractor

public static <T> void filterByType(Device[] devices, Function<Device, T> extractor, T expect) {
    if (devices == null) {
        return;
    }
    for (int i = 0; i < devices.length; i++) {
        if (devices[i] == null) {
            continue;
        }
        Object actual = extractor.apply(devices[i]);
        if (actual == null && expect== null) {
            continue;
        } else if (actual  == null) {
            devices[i] = null;
            continue;
        }
        if (!Objects.equals(actual, expect)) {
            devices[i] = null;
        }
    }
}
publicstaticvoidfilterbytype(设备[]设备,函数提取器,T expect){
如果(设备==null){
返回;
}
对于(int i=0;i
这是一个更简单的版本。您可以使用原始类型,但这样更容易出错

public static <T> void filtrateByType(T[] objects, Function<T, String> function, String type) {
    if (objects == null || type == null)
        return;
    for (int i = 0; i < objects.length; i++) {
        if (objects[i] == null) continue;
        String match = function.apply(objects[i]);
        if (match == null || !match.equals(type)) 
            objects[i] = null;
    }
}

“没有泛型”?你可以,但为什么?我猜这家伙还在起步,如果是这样的话,泛型是一个高级话题。你必须先学会走路,然后才能跑:)你可以使用策略模式——rawtypes的建议让我很难过……我更喜欢我的无泛型方法。这是公平的——但我想如果需要的话,可以对方法引用进行去语法化。我本来打算编写提取器的实现,也许会将它们放在枚举中,等等——但我决定这不会给答案增加太多内容流方法很好,似乎问题空间是就地更新数组。流示例是否会创建一个无法从现有方法返回的新数组(因为现有方法被声明为void)?或者我在这里误解了什么?@KevinO这是真的,但是
null
out数组中的值来实现过滤器与创建只包含所需元素的数组相比是相对丑陋的。它使用的是通用接口,但可能更糟,声明该函数的正确方法是:
public void filtrateBy(E[]设备,功能作者不要求使用泛型,所以你决定使用比平时更少的泛型-即糟糕的泛型。我不确定我是否遵循…附言。所有的通配符都是完全不必要的。好吧,这取决于作者为什么不要求使用泛型。也许是因为家庭作业禁止他们使用泛型,但这也不是一个好问题如果他们是一个新的程序员,并且对泛型感到困惑,那么使用较少的泛型对他们来说是一个很好的方法,可以让他们了解基础知识,不再害怕泛型和通配符。最后,唯一的“合法的”原因是使用了不支持泛型的较旧版本的Java,但我已经用“使用Java 8魔术”开始了我的答案,清楚地说明这个解决方案仅适用于Java 8+。我仍然不明白。如果我问了一个问题并说“我在使用Java 8,请坚持这个”你会在不是Java11的情况下使用Java10特性吗?对不起,但我真的认为问题很清楚,这并不能回答问题。
public static <T> void filtrateByType(T[] objects, Function<T, String> function, String type) {
    if (objects == null || type == null)
        return;
    for (int i = 0; i < objects.length; i++) {
        if (objects[i] == null) continue;
        String match = function.apply(objects[i]);
        if (match == null || !match.equals(type)) 
            objects[i] = null;
    }
}
Device[] filtered = Stream.of(devices)
                          .filter(d -> Objects.equals(d.getType(), type))
                          .toArray(Device[]::new);