【问题标题】:Verify there is a combination of unique string验证是否存在唯一字符串的组合
【发布时间】:2018-12-01 12:39:39
【问题描述】:
class Details{
 String name;
 String age;
 String email;
 String location;
}

1) 如果有List<Details> 中的详细信息列表,如何验证姓名和电子邮件的组合是否共同唯一。 (即)对于一个电子邮件地址,不能有两个姓名条目。

2) 如何验证类文件中所有字段的组合是否唯一。

解决这个问题的完美数据结构是什么?

【问题讨论】:

    标签: java algorithm scala data-structures


    【解决方案1】:

    如果您只需要实现唯一值,则应使用Set。您必须使用自己的 equals & hashCode 实现,例如,对于案例 1):

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Details details = (Details) o;
        return Objects.equals(name, details.name) &&
                Objects.equals(email, details.email);
    }
    
    @Override
    public int hashCode() {
    
        return Objects.hash(name, email);
    }
    

    如果您需要所有 Details 成员都是唯一的,只需使用所需属性更新 hash & equals 实现。

    【讨论】:

      【解决方案2】:

      您可以通过# 之类的分隔符对值进行哈希处理,然后找出所有唯一值。 Details 的哈希值在第一种情况下是 name + "#" + "email,在第二种情况下是 name + "#" + age + "#" + email + "#" + location。 如果Details 的每个实例有任何具有指定键(或哈希)的重复项,您可以使用Hashmap 查找重复项。

      【讨论】:

      • 这里为什么需要#?
      • @Sree 因为如果您有name = omemail = g@e.c,那么name = oemail = mg@e.c 的哈希值相同!因此,您需要nameemail 中不存在的分隔符。
      【解决方案3】:

      当您覆盖任何对象中的 equals 方法时,您可以完美地检查该对象与另一个对象的相等性即使它们位于内存中的不同位置。

      所以下面的代码

      myList.contains(myObject);

      如果在 myList 中有一个对象,其 equals 方法使用 myObject 返回 true,则将作出响应。

      在所有主要的 IDE(如 intelliJ、netbeans、eclipse 等)中,IDE 将帮助您准确地覆盖 equals 方法。这是使用 intelliJ IDE

      覆盖 equals 方法的自动生成代码
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
          Details details = (Details) o;
          return Objects.equals(name, details.name) &&
                  Objects.equals(email, details.email);
      }
      

      现在,如果您想避免在列表中添加重复项,您应该使用 Set 而不是 List >Set 将添加一个新元素如果 hashCodeequals 方法的组合不同(比较现有对象和新预期添加对象)

      所以我们必须重写 hashCode 方法(由 intelliJ IDE 生成)如果我们想使用 Set 类的风格

      @Override
      public int hashCode() {
          return Objects.hash(name, email);
      }
      

      现在,如果您创建一个集合并尝试在该集合中添加两个具有相似名称和电子邮件的对象,该集合将仅添加第一个唯一名称和电子邮件地址,即使第二个对象的其他字段有不同的值

      import java.util.HashSet;
      import java.util.Objects;
      import java.util.Set;
      
      class Details {
          String name;
          String age;
          String email;
          String location;
      
          public Details(String name, String age, String email, String location) {
              this.name = name;
              this.age = age;
              this.email = email;
              this.location = location;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Details details = (Details) o;
              return Objects.equals(name, details.name) &&
                      Objects.equals(email, details.email);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(name, email);
          }
      
          @Override
          public String toString() {
              return String.format("(name: %s, age: %s, email: %s, location: %s)", name, age, email, location);
          }
      
          public static void main(String[] args) {
              Set<Details> mySet = new HashSet<>();
              mySet.add(new Details("Mehdi", "12", "123@xyz.com", "Los Angeles"));
              mySet.add(new Details("Mehdi", "34", "123@xyz.com", "Las Vegas"));
              System.out.println(mySet);
          }
      
      }
      

      这是整个测试应用程序。还有其他值得一提的。如果在任何情况下您已将数据保存在列表中,并且您想根据您拥有的规则(例如姓名、电子邮件)删除重复项,您可以尝试这种方法:

      Set<Details> mySet = new HashSet<>(myList);
      

      哪个 myList 是你的列表。 所以在你的应用中会是这样的:

      public static void main(String[] args) {
          List<Details> myList = new ArrayList<>();
          myList.add(new Details("Mehdi", "12", "123@xyz.com", "Los Angeles"));
          myList.add(new Details("Mehdi", "34", "123@xyz.com", "Las Vegas"));
      
          Set<Details> mySet = new HashSet<>(myList);
          System.out.println(mySet);
      }
      

      这是没有任何重复的结果:

      [(姓名:Mehdi,年龄:12,电子邮件:123@xyz.com,地点:洛杉矶)]

      【讨论】:

        【解决方案4】:

        除了使用@OmG 提出的哈希值之外,您还可以使用 TreeSet,其键是唯一字段的串联,也可以在它们之间使用分隔符。

        Set 只承认唯一键。

        【讨论】:

          猜你喜欢
          • 2016-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-01
          • 1970-01-01
          • 2014-06-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多