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 reference:LocalDate :: 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 );
我有一个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 reference:LocalDate :: 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 );