0

我有一个用于根据对象的多个属性过滤一组对象的用例。我将在 Javascript 中使用的一种方法可能是创建一个仅包含我关心的属性的对象,然后根据我希望过滤的对象检查这些属性名称。

示例(在打字稿中):

example(): void {
    let template = {
        name: 'Test',
        color: 'Blue'
    };

    let objects = [
        { name: 'Test', color: 'Blue' },
        { name: 'Test2', color: 'Blue' },
        { name: 'Test', color: 'Red' },
        { name: 'Test', color: 'Blue', extra: true },
    ];

    let results = objects.map(o => this.compare(o, template));
    console.log(results);
}

compare(obj, template): boolean {
    for (const prop in template) {
        if (obj[prop] !== template[prop]) {
            return false;
        }
    }

    return true;
}

以上将写入[true, false, false, true]控制台。这很酷的原因是它基本上可以接受任何对象并发出正确的结果。如何在 Java 中提供此功能对我来说并不明显,这样我就可以避免在数百个数据模型 bean 上实现比较功能。

是否有一种内置或常用的方法可以以通用方式在 Java 中进行等效比较?

4

2 回答 2

1

这可以使用反射来完成:

public static boolean compare(Object object, Object template) {
  Field[] templateFields = template.getClass().getDeclaredFields();
  try {
    for (Field templateField : templateFields) {
      Field objectField = object.getClass().getDeclaredField(templateField.getName());
      templateField.setAccessible(true);
      objectField.setAccessible(true);
      if (!objectField.get(object).equals(templateField.get(template))) {
        return false;
      }
    }
  } catch (Exception e) {
    return false;
  }
  return true;
}

(这段代码只是展示了这个想法,并没有涵盖所有可能的情况,例如不检查继承的字段)

我不知道内置或常用的方法来做到这一点。有一些用于严格比较的实用程序(通常用于单元测试),不确定它们是否适用于您的用例。

请注意,Java 9 模块可以限制对对象的反射访问。

于 2019-11-15T19:07:13.633 回答
0

您可以使用流进行这样的操作:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

class MyObjectTest {

    @Test
    void test() {
        MyObject template = new MyObject("Test", "Blue");

        List<MyObject> objects = new ArrayList<>();
        objects.add(new MyObject("Test", "Blue"));
        objects.add(new MyObject("Test2", "Blue"));
        objects.add(new MyObject("Test", "Red"));
        objects.add(new MyObject("Test", "Blue", true));

        List<MyObject> results = objects.stream()
                                        .filter(myObject -> myObject.getName().equals(template.getName())
                                                && myObject.getColor().equals(template.getColor()))
                                        .collect(Collectors.toList());
        System.out.println("results = " + results);
    }

    static class MyObject {
        private final String name;
        private final String color;
        private final boolean extra;

        public MyObject(String name, String color) {
            this.name = name;
            this.color = color;
            this.extra = false;
        }

        public MyObject(String name, String color, boolean extra) {
            this.name = name;
            this.color = color;
            this.extra = extra;
        }

        public String getName() {
            return name;
        }

        public String getColor() {
            return color;
        }
    }
}
于 2019-11-15T17:09:33.067 回答