Java: выяснение, все ли числовые поля объекта равны 0 - PullRequest
0 голосов
/ 28 августа 2018

У меня есть класс Java-8:

  class MyClass{
    double field1;
    double field2;
    int field3;
    ...
    float fieldN;

    boolean isEmpty() {
        // I want to implement this such that if all my numeric fields are 0's then return true else false
    }

}

Что было бы наиболее элегантным способом реализации isEmpty () вместо добавления множества различных условий if (fieldX == 0)?

Ответы [ 4 ]

0 голосов
/ 28 августа 2018

Самый элегантный способ - использовать проверка бинов JSR 380 .

Это набор инструментов, включая полезные общие аннотации , для определения метаданных класса бина для проверки ограничения.

Вам не нужно читать полную спецификацию, чтобы понять суть:

Вы хотите определить групповой класс для этого конкретного набора ограничений

public interface MyCustomIsEmpty{}

Затем аннотируйте каждое соответствующее поле с помощью

@Max(value = 0, groups = { MyCustomIsEmpty.class })
@Min(value = 0, groups = { MyCustomIsEmpty.class })

убедитесь, что используются классы аннотаций javax.validation.constraints.

Теперь ваш фактический isEmpty () будет таким же простым, как получение валидатора по умолчанию и проверка текущего экземпляра:

public boolean isEmpty() {
    // Gets validator instance from factory
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    validator = factory.getValidator();    

    // Validates 'this' using only fields belonging to the MyCustomIsEmpty group
    Set<ConstraintViolation<MyClass>> constraintViolations = validator.validate(this, MyCustomIsEmpty.class);

    // there are lots of fancy things you could do but this covers your case 
    return constraintViolations.isEmpty();
}

Вы можете упростить эквивалент двух объединенных аннотаций в одну пользовательскую для меньшей детализации. Это описано в спецификации.

0 голосов
/ 28 августа 2018

YMMV о том, считаете ли вы его «элегантным», но вы можете использовать DoubleStream:

boolean isEmpty() {
    return DoubleStream.of(field1, field2, field3)
        .allMatch(f -> f == 0);
}
0 голосов
/ 28 августа 2018

, если вы не хотите объявлять каждое поле, и если вы еще можете использовать отражение и потоковый фильтр

public boolean isEmpty()  throws IllegalAccessException {
    Field[] valueObjFields = this.getClass().getDeclaredFields();

    Object _this=this;
    return Arrays.stream(valueObjFields).allMatch(o -> {
        try {
            return Double.parseDouble(o.get(_this).toString())== 0;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    });
}

этот метод возвращает true, если все поля пусты и вам не нужно проверять каждое поле отдельно.

Даже если вы добавите больше полей в класс, этот метод будет работать без изменения.

0 голосов
/ 28 августа 2018

Вы можете использовать что-то вроде общего списка, добавляя свои значения в этот список и повторяя его.

List<Object> field = new List<Object>

или использование Number вместо Object.

Тогда ваш isEmpty () может выглядеть так:

boolean isEmpty() {
    for (Object o : field) {
        if (o == 0) return false;
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...