【问题标题】:Checking equals for JAXB object considering some of the fields考虑某些字段检查 JAXB 对象的等于
【发布时间】:2013-08-07 15:41:24
【问题描述】:

我的自动生成的 JAXB 类

public class Employee {
   private int id;
   private String name;
   private String department;

   /* Getters and Setters */

}

Employee emp1 = new Employee();
emp1.setId(1);
emp1.setName("A");
emp1.setDepartment("D1");


Employee emp2 = new Employee();
emp2.setId(2);
emp2.setName("B");
emp2.setDepartment("D1");

List<Employee> empList1 = new ArrayList<Employee>();
empList1.add(emp1);
empList2.add(emp2);

Employee emp3 = new Employee();
emp2.setId(3);
emp2.setName("A");
emp2.setDepartment("D1");

List<Employee> empList2 = new ArrayList<Employee>();
empList2.add(emp3);

我想比较列表 empList1 和 empList2 并获得一个匹配 Employee 对象的名称和部门字段的结果列表。

基本上,我需要基于两个对象中字段的自定义比较来交叉两个列表。

我正在查看 Google Guava 和 lambdaJ,但我无法找到通过自定义比较逻辑进行交集的解决方案/示例。

任何想法都会有所帮助。

【问题讨论】:

    标签: java collections guava


    【解决方案1】:

    您可以使用 Guava Ordering 或 Java Comparator 进行比较。对于过滤,您可以使用谓词。

    如果您想要通用的东西,您可以使用制作一个比较器(用于 DEP 和 NAME)

        class MyComparator implements Comparator<Employee> {
    
            @Override
            public int compare(final Employee left, final Employee right) {
                return ComparisonChain.start().compare(left.getName(), right.getName())
                                      .compare(left.getDepartment(), right.getDepartment()).result();
            }
    
        }
    
        class MyPredicate implements Predicate<Employee> {
    
            final List<Employee> employees;
            final Comparator<Employee> comparator;
    
            public MyPredicate(final List<Employee> employees, final Comparator<Employee> comparator) {
                this.employees = employees;
                this.comparator = comparator;
            }
    
            @Override
            public boolean apply(@Nullable final Employee input) {
                for (final Employee e : employees) {
                    if (comparator.compare(e, input) == 0) {
                        return true;
                    }
    
                }
    
                return false;
            }
    
        }
    

    然后你可以这样使用它:

        final MyComparator comparator = new MyComparator();
        final MyPredicate predicate1 = new MyPredicate(empList1, comparator);
        final MyPredicate predicate2 = new MyPredicate(empList2, comparator);
        System.out.println("####");
        System.out.println(Collections2.filter(empList2, predicate1));
        System.out.println(Collections2.filter(empList1, predicate2));
    

    【讨论】:

      【解决方案2】:
      public List<Employee> findIntersections(List<Employee> listA, List<Employee> listB)
      {
      
          List<Employee> returnList = new List<Employee>();
          Employee empA, empB;
      
          for(int i = 0; i<listA.size; i++)
          {
              for(int j = 0; j<listB.size; j++)
              {
                  empA = listA.get(i);
                  empB = listB.get(j);
      
                  if(empA.getID == empB.getID() && empA.getName().equals(empB.getName()) && empA.getDepartment().equals(empB.getDepartment()))
                  {
                      returnList.add(empA);//or add empB...since theyre the same
                  }
              }
          }
      
          return returnList;
      }
      

      我想要一个通用的实现。有很多 JAXB 对象 需要基于字段的平等检查。有没有类似的东西 比较器哪个有返回布尔值的方法?

      这是我发现的(你可能需要一个插件):

      不幸的是,jaxb 没有提供这个开箱即用的功能。您可以使用 这个plugin,或者编写你自己的以获得更多可定制的行为。

      来源:

      https://stackoverflow.com/a/7771776/2498729

      【讨论】:

      • 我想要一个通用的实现。有很多 JAXB 对象需要基于字段进行相等检查。是否有类似于 Comparator 的具有返回布尔值的方法?
      【解决方案3】:

      手动破解一个方法来交叉两个列表将是最快的方法。但是,如果您需要更通用的方法来处理 Employee 以外的其他内容,例如,您可以使用番石榴 Equivalence 类。这样,您可以将列表中的条目映射到 Equivalence.Wrapper 并在这些包装集上使用 Sets.intersect。

      public static <T> Set<T> intersect(Iterable<? extends T> a, Iterable<? extends T> b, Equivalence<? super T> eq) {
          Function<T, Wrapper<T>> f = wrappingFunction(eq);
      
          Set<Wrapper<T>> as = ImmutableSet.copyOf(Iterables.transform(a, f));
          Set<Wrapper<T>> bs = ImmutableSet.copyOf(Iterables.transform(b, f));
      
          SetView<Wrapper<T>> intersection = Sets.intersection(as, bs);
      
          return ImmutableSet.copyOf(Iterables.transform(intersection,
                  Test.<T> unwrappingFunction()));
      }
      

      wrappingFunction() 和unwrappingFunction() 有两个实用函数:

          public static <T> Function<T, Wrapper<T>> wrappingFunction(
              final Equivalence<? super T> eq) {
          return new Function<T, Wrapper<T>>() {
              public Wrapper<T> apply(T input) {
                  return eq.wrap(input);
              }
          };
      }
      
      private static final Function<Wrapper<Object>, Object>  UNWRAPPING_FUNCTION = new Function<Wrapper<Object>, Object>() {
      
          public Object apply(Wrapper<Object> input) {
              return checkNotNull(input).get();
          }
      };
      
      @SuppressWarnings("unchecked")
      public static <T> Function<Wrapper<T>, T> unwrappingFunction() {
          return ((Function<Wrapper<T>, T>) ((Function<?, ?>) UNWRAPPING_FUNCTION));
      }
      

      有了这个,您必须为Employee 实施Equivalence 并应用intersect

      Set<Employee> x = intersect(a, b, new Equivalence<Employee>() {
      
              @Override
              protected boolean doEquivalent(Employee a, Employee b) {
                  checkNotNull(a);
                  checkNotNull(b);
                  return Objects.equals(a.getId(), b.getId())
                      && Objects.equals(a.getDepartment(), b.getDepartment())
                      && Objects.equals(a.getName(), b.getName());
              }
      
              @Override
              protected int doHash(Employee t) {
                  return t.getId();
              }
          });
      

      在此示例中,返回的 Set 不会包含重复的 Employees。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 1970-01-01
        • 2018-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多