【问题标题】:How to check list object has null value or empty string?如何检查列表对象有空值或空字符串?
【发布时间】:2021-11-26 10:45:10
【问题描述】:

我有一个 Book 课程,然后我创建了一个 List<Book>。我在检查所有属性时遇到问题。以下是class Book 的程序代码示例:

class Book {  
    int id;  
    String name,author;
    public Book(int id, String name, String author) {  
        this.id = id;  
        this.name = name;  
        this.author = author;  
    }   
}

这是List<Book> 上的代码 sn-p :

 Book b = new Book(1, "", "Ok");
 Book c = new Book(2, "Z", "");
 Book d = new Book(0, "C", "Ok");
 List<Book> x = new ArrayList<>();
 x.add(b);
 x.add(c);
 x.add(d);

如何检查 List&lt;Book&gt; 中的值是 string empty 还是 null,然后返回 Boolean 并返回消息示例 id 2 has empty value

【问题讨论】:

  • 什么是Book d = new Book(, "C", "Ok");?它是如何编译的?
  • 只是一个例子@AlexeyR。
  • 示例必须具有代表性和可重复性。
  • 好吧,对不起@AlexeyR。
  • 字段id 是原始int,因此不能是null

标签: java list arraylist


【解决方案1】:

您可以使用Apache Commons 中的StringUtils.isEmpty(...) 方法,或者如果您不想要依赖项,您可以这样写:

public static boolean isEmpty(String s) {
  return s == null || s.isEmpty();
}

要检查List 中的所有authors,请使用Streams:

public boolean anyAuthorEmpty(List<Book> books) {
  return books.stream().anyMatch(b -> isEmpty(b.getAuthor());
}

要找到确切的Book,您可以像这样使用.findFirst()

public Book findBookWithEmptyAuthor(List<Book> books) {
  return books.stream().filter(b -> isEmpty(b.getAuthor())
                .findFirst().orElse(null);
}

如果没有找到,这将返回 Booknull

如果你需要所有没有作者的你可以使用Collectors.toList():

public List<Book> findBooksWithNoAuthor(List<Book> books) {
  return books.stream().filter(b -> isEmpty(b.getAuthor())
                .collect(Collectors.toList());

【讨论】:

  • 要求是准确返回哪些对象有空author。您也需要添加该部分。
  • 不一一调用属性还有其他方法吗? @csalmhof
  • 是的,你说的是真的@SreeKumar
  • @senaa 您可以使用多个过滤器或过滤器以获取更多值,例如一个方法findBooksWithEmptyValue(List&lt;Book&gt; books)。然后过滤器看起来像.filter(b -&gt; (isEmpty(b.getAuthor() || isEmpty(b.getName()))。但是随后您丢失了信息,该字段为空。如果您想全面检查任何 String-Field 是否为 null 或为空,您应该使用 @alexey-r 在 this answer 中提到的反射。
【解决方案2】:

要检查类Book的多个属性,可以提供以下解决方案(前提是有辅助方法isNullOrEmpty的实现):

class SONullEmpty {
    static boolean isNullOrEmpty(String str) {
        return str == null || str.isEmpty();
    }

    static List<Book> booksWithNullOrEmpty(List<Book> books) {
        return books
            .stream()
            .filter(book -> Stream.of(
                    book.getName(), book.getAuthor()
                ).anyMatch(SONullEmpty::isNullOrEmpty)
            )
            .collect(Collectors.toList());
    }
}

类似地,可以实现一个接受多个 Book 属性的 getter 的方法,然后调用:

// in the same SONullEmpty class
static List<Book> withNullOrEmptyAttribs(List<Book> books, Function<Book, String> ... getters) {
    return books
        .stream()
        .filter(book -> Arrays.stream(getters).anyMatch(g -> isNullOrEmpty(g.apply(book))))
        .collect(Collectors.toList());
}

测试:

Book b = new Book(1, "", "Ok");
Book c = new Book(2, "Z", "");
Book d = new Book(3, null, "Ok");
List<Book> x = Arrays.asList(b, c, d);

withNullOrEmptyAttribs(x, Book::getName)
    .forEach(book -> System.out.printf("Book with id=%d has null or empty name%n", book.getId()));

withNullOrEmptyAttribs(x, Book::getAuthor)
    .forEach(book -> System.out.printf("Book with id=%d has null or empty author%n", book.getId()));

输出:

Book with id=1 has null or empty name
Book with id=3 has null or empty name
Book with id=2 has null or empty author

【讨论】:

    【解决方案3】:

    您可以使用反射,这样您就不需要单独手动测试每个文件:

    static void testAllFieldsForNull(List<Book> bookList) throws IllegalAccessException {
        for (int i = 0; i < bookList.size(); i++){
            Book book = bookList.get(i);
            Field[] fields = book.getClass().getDeclaredFields();
            for(Field field: fields){
                Class<?> fieldType = field.getType();
                if(!fieldType.isPrimitive()){
                    if (field.get(book) == null){
                        System.out.println("Field [" + field.getName() + "] has null value for book at position " + i);
                        continue;
                    }
                    if(fieldType.isAssignableFrom(String.class) && ((String)field.get(book)).isEmpty()){
                        System.out.println("Field [" + field.getName() + "] is empty String for book at position " + i);
                    }
                }
            }
        }
    }
    

    测试:

    public static void main(String[] args) throws IllegalAccessException {
        Book b = new Book(1, "", "Ok");
        Book c = new Book(2, "Z", "");
        Book d = new Book(0, "C", null);
        List<Book> x = new ArrayList<>();
        x.add(b);
        x.add(c);
        x.add(d);
        testAllFieldsForNull(x);
    }
    

    输出:

    Field [name] is empty String for book at position 0
    Field [author] is empty String for book at position 1
    Field [author] has null value for book at position 2
    

    或者,如果您只需要收集“好”书籍(实际上是任何类型的物品),您可以使用:

    public static boolean testObject(Object obj){
        Field[] fields = obj.getClass().getDeclaredFields();
        boolean okay = true;
        for(Field field: fields){
            Class<?> fieldType = field.getType();
            try{
                if(!fieldType.isPrimitive()){
                    if (field.get(obj) == null){
                        okay = false;
                        continue;
                    }
                    if(fieldType.isAssignableFrom(String.class) && ((String)field.get(obj)).isEmpty()){
                        okay = false;
                    }
                }
            }catch (IllegalAccessException e){
                e.printStackTrace();
                return false;
            }
        }
        return okay;
    }
    

    然后将其用于过滤:

    public static void main(String[] args) throws IllegalAccessException {
        Book b = new Book(1, "", "Ok");
        Book c = new Book(2, "Z", "");
        Book d = new Book(0, "C", null);
        Book a = new Book(3, "C", "D");
        List<Book> x = new ArrayList<>();
        x.add(b);
        x.add(c);
        x.add(d);
        x.add(a);
        System.out.println(
                x
                .stream()
                .filter(FieldTest::testObject)
                .collect(Collectors.toList()).get(0).id
        );
    }
    

    【讨论】:

      【解决方案4】:

      或者你也可以使用 Java Stream

      public class Test1 {
          private Test1()
          {
              Book b = new Book(1, "", "Ok");
              Book c = new Book(2, "Z", "");
              Book d = new Book(3, "C", "Ok");
              List<Book> x = new ArrayList<>();
              x.add(b);
              x.add(c);
              x.add(d);
              
              boolean empty = x.stream()
                      .filter(book -> book.name == null || book.name.isEmpty() || book.author == null || book.author.isEmpty())
                      .count() > 0;
          }
      
          class Book
          {
              int id;
              String name, author;
      
              public Book(int id, String name, String author)
              {
                  this.id = id;
                  this.name = name;
                  this.author = author;
              }
          }
          
          public static void main(String[] args)
          {
              new Test1();
          }
      }
      

      【讨论】:

      • 您好Eddy先生,有没有其他方法可以不用一一调用属性?
      • 是的,使用 Java 反射或 Book 类中的新方法可以测试当前书籍的所有字符串,然后您只需为每个书籍对象调用它以检查是否有 Book有一个空字符串
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 2013-04-11
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      相关资源
      最近更新 更多