仅使用标准
Java库,什么是将字符串连接到限制的简单机制,并在限制导致更短的字符串时附加省略号?
效率是可取的.连接所有字符串然后使用String.substring()可能会消耗过多的内存和时间.可以在Java 8流管道中使用的机制是可取的,因此甚至可能永远不会创建超过限制的字符串.
就我的目的而言,我很满意以下两种方式表达的限制:
>要加入的最大字符串数
>结果中的最大字符数,包括任何分隔符.
例如,这是使用标准库在Java 8中强制执行最大数量的连接字符串的一种方法.有更简单的方法吗?
final int LIMIT = 8; Set<String> mySet = ...; String s = mySet.stream().limit( LIMIT ).collect( Collectors.joining(",")); if ( LIMIT < mySet.size()) { s += ",..."; }
解决方法
您可以为此编写自定义收集器.这个是基于
another I wrote for a similar case:
private static Collector<String,List<String>,String> limitingJoin(String delimiter,int limit,String ellipsis) { return Collector.of( ArrayList::new,(l,e) -> { if (l.size() < limit) l.add(e); else if (l.size() == limit) l.add(ellipsis); },(l1,l2) -> { l1.addAll(l2.subList(0,Math.min(l2.size(),Math.max(0,limit - l1.size())))); if (l1.size() == limit) l1.add(ellipsis); return l1; },l -> String.join(delimiter,l) ); }
在这段代码中,我们保留一个ArrayList< String>所有受欢迎的弦乐队.当一个元素被接受时,当前列表的大小将根据限制进行测试:严格小于它,添加元素;等于它,省略了省略号.对于组合器部分也是如此,这有点棘手,因为我们需要正确处理子列表的大小而不超过限制.最后,终结者只是使用给定的分隔符加入该列表.
此实现适用于并行Streams.它将保留Stream in encounter order的head元素.请注意,即使在达到限制后没有添加任何元素,它也会消耗Stream中的所有元素.
工作范例:
List<String> list = Arrays.asList("foo","bar","baz"); System.out.println(list.stream().collect(limitingJoin(",",2,"..."))); // prints "foo,bar,..."