实施 CharSequence 以便使用 String.join?
Implement CharSequence in order to use String.join?
我有一个全部覆盖 toString()
的对象集合。
我想将它们写出来以控制台或连接到一个字符串,基本上为集合创建一个 toString()
。
我可以使用 for 循环来实现这一点。 String.join()
似乎是一种更好的方法,因为它消除了显式循环:
import java.util.ArrayList;
public class Foo
{
private double member;
public Foo()
{
member = Math.random();
}
@Override
public String toString()
{
return "I'm foo " + member;
}
public static void main(String[] args)
{
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
// print collection with loop
for (Foo foo : foos)
{
System.out.println(foo);
}
// print collection with String.join
System.out.println(String.join(System.lineSeparator(), foos)); // fails
}
}
要使System.out.println()
起作用,需要调用toString()
方法。无需显式实现任何接口。这似乎很容易,也是一种常见的做法。
但是,得到String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
to work, merely having a toString()
method is not enough. I need an Iterable<? extends CharSequence>
, which means Foo
should implement CharSequence
。
现在我通过委托 toString()
:
快速实现了那个接口
import java.util.ArrayList;
import java.util.stream.IntStream;
import java.lang.CharSequence;
public class Foo implements CharSequence
{
private double member;
public Foo()
{
member = Math.random();
}
@Override
public char charAt(int index)
{
return toString().charAt(index);
}
@Override
public IntStream chars()
{
return toString().chars();
}
@Override
public IntStream codePoints()
{
return toString().codePoints();
}
@Override
public int length()
{
return toString().length();
}
@Override
public CharSequence subSequence(int start, int end)
{
return toString().subSequence(start, end);
}
@Override
public String toString()
{
return "I'm foo " + member;
}
public static void main(String[] args)
{
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
System.out.println(String.join(System.lineSeparator(), foos));
}
}
但这似乎是相当多的代码,在这种情况下除了保证将对象转换为 String
的可能性外,每个 Object
在toString()
.
的形式
解决方案中引入的样板代码比它删除的样板代码大。
我怎样才能让 class 和 String.join()
玩得开心?
我应该走那条路并实现接口还是应该 运行 即时进行一些转换?
根据用法,该路由可能效率低下,因为每次调用 CharSequence 方法都会重新调用 toString。例如,如果一个方法试图遍历每个字符,您将看到糟糕的性能。既然你正在使用 Java 8,为什么不使用 Streams API?
System.out.println(foos.stream()
.map(Object::toString)
.collect(Collectors.joining(System.lineSeparator())));
我有一个全部覆盖 toString()
的对象集合。
我想将它们写出来以控制台或连接到一个字符串,基本上为集合创建一个 toString()
。
我可以使用 for 循环来实现这一点。 String.join()
似乎是一种更好的方法,因为它消除了显式循环:
import java.util.ArrayList;
public class Foo
{
private double member;
public Foo()
{
member = Math.random();
}
@Override
public String toString()
{
return "I'm foo " + member;
}
public static void main(String[] args)
{
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
// print collection with loop
for (Foo foo : foos)
{
System.out.println(foo);
}
// print collection with String.join
System.out.println(String.join(System.lineSeparator(), foos)); // fails
}
}
要使System.out.println()
起作用,需要调用toString()
方法。无需显式实现任何接口。这似乎很容易,也是一种常见的做法。
但是,得到String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
to work, merely having a toString()
method is not enough. I need an Iterable<? extends CharSequence>
, which means Foo
should implement CharSequence
。
现在我通过委托 toString()
:
import java.util.ArrayList;
import java.util.stream.IntStream;
import java.lang.CharSequence;
public class Foo implements CharSequence
{
private double member;
public Foo()
{
member = Math.random();
}
@Override
public char charAt(int index)
{
return toString().charAt(index);
}
@Override
public IntStream chars()
{
return toString().chars();
}
@Override
public IntStream codePoints()
{
return toString().codePoints();
}
@Override
public int length()
{
return toString().length();
}
@Override
public CharSequence subSequence(int start, int end)
{
return toString().subSequence(start, end);
}
@Override
public String toString()
{
return "I'm foo " + member;
}
public static void main(String[] args)
{
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
foos.add(new Foo());
System.out.println(String.join(System.lineSeparator(), foos));
}
}
但这似乎是相当多的代码,在这种情况下除了保证将对象转换为 String
的可能性外,每个 Object
在toString()
.
解决方案中引入的样板代码比它删除的样板代码大。
我怎样才能让 class 和 String.join()
玩得开心?
我应该走那条路并实现接口还是应该 运行 即时进行一些转换?
根据用法,该路由可能效率低下,因为每次调用 CharSequence 方法都会重新调用 toString。例如,如果一个方法试图遍历每个字符,您将看到糟糕的性能。既然你正在使用 Java 8,为什么不使用 Streams API?
System.out.println(foos.stream()
.map(Object::toString)
.collect(Collectors.joining(System.lineSeparator())));