Java 使用流将对象列表过滤为字符串数组

Java filtering the object list to string array with stream

我有一个class这样的

public class Host {

  private HTMLToken.TokenType type;
  private StringBuilder content;

  public Host(HTMLToken.TokenType type) {
    this.type = type;
    content = new StringBuilder();
  }


  String contentAsString() {
    return content.toString();
  }

  void addStrig(String x) {
    content.append(x);
  }

  public enum TokenType {
    TAG, TEXT
  }

}

和这样的静态函数

 public static String[] filterLength(List<Host> hostList, int length) {
    return hostList.stream().filter(str -> str.contentAsString().length() > length)
        .toArray(String[]::new);
  }

问题出在 filterLength 函数内部 我不能 return 作为字符串数组流式传输(我想 return 主机 class 中的内容)因为 List 包含主机对象我怎样才能 return 作为 1 行代码中的字符串?

转换流中的每个对象

您正在成功地将一堆 Host 对象流式传输、过滤和收集到一个数组中。但是您似乎在问如何改为收集每个 Host 对象的 字符串表示形式

因此,您需要在流操作中添加一个步骤。对于每个 Host 个对象,我们要生成并收集一个 String 个对象。

Stream#map

要从正在流式传输的对象转换为不同类型的对象,请使用 Stream#map

这是您的代码的模拟,使用 LocalDate. We transform each filtered LocalDate object to a String object by passing a method referenceLocalDate :: toString

List < LocalDate > dates = new ArrayList<>( 4 ) ;
dates.add( LocalDate.of( 2022 , Month.JANUARY, 11 ) ) ;
dates.add( LocalDate.of( 2022 , Month.JANUARY, 12 ) ) ;
dates.add( LocalDate.of( 2022 , Month.JANUARY, 13 ) ) ;
dates.add( LocalDate.of( 2022 , Month.JANUARY, 14 ) ) ;

String[] results = 
    dates
    .stream()
    .filter( localDate -> localDate.getDayOfMonth() > 12 )
    .map( LocalDate :: toString )  //  
    .toArray( String[] :: new ) ;

System.out.println( "results = " + String.join( ", " , results ) ) ;

看到这个 code run live at IdeOne.com

results = 2022-01-13, 2022-01-14

我看到你有一个 contentAsString 方法。我会猜测那个方法 returns 你想要收集的文本类型。

因此您的代码应该类似于以下内容,将方法引用 Host :: contentAsString 传递给 Stream#map

return 
    hostList
    .stream()
    .filter( str -> str.contentAsString().length() > length )
    .map( host -> Host::contentAsString )  //  Add this step.
    .toArray( String[]::new );

该代码有效但效率低下。无需为每个输入执行两次 contentAsString 方法。我们可以通过先调用 map 来解决这个问题,然后根据已经生成的字符串的长度进行过滤。

return 
    hostList
    .stream()
    .map( host -> Host::contentAsString )  //  Add this step.
    .filter( string -> string.length() > length )  //  Change this step.
    .toArray( String[]::new );