google / guava

Google core libraries for Java

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature] Add ability for Joiner to truncate

rwinograd opened this issue · comments

I often write code of the flavor: log.info("Array items: [{}]", Joiner.on(",").join(array)). This code is somewhat brittle for extremely long lists, but I have no convenient way to truncate the list while still indicating that the list has been truncated.

It would be nice if there was some way to both truncate the list to a fixed number of values, but also show within the joined string that it has been truncated. So for example, to borrow from the Ascii#truncate API:
log.info("Array items: [{}]", Joiner.on(",").withTruncationIndicator("...").join(array))

I have started working on this. Can this is be added to hacktoberfest? Please assign this to me and add the label "hacktoberfest"

Hello! A few things

background

First, for some general background, we're reluctant to make more changes to Joiner as we feel that it's been largely superseded by new features in the JDK -- I see that we haven't documented this fact yet and will make a note of it. (I don't know offhand whether it might have the feature you want.)

I think your example usage is missing the part that specifies how long to truncate after. And in fact there are two cases: truncating by list length, or by string length.

by string length

Truncating a string by length is actually unsolvable in an internationalized context (literally you have to render an image file and then truncate that), so I wouldn't approach it outside of a class named Ascii.

The obvious problem with just passing the result of join to Ascii.truncate is that by then you already built the giant string. I might try creating a length-capped Appendable and then joinTo that. You could have it throw IOException upon hitting the limit, and catch that outside the usage code, but exceptions are so expensive (and that code so ugly) that it's probably better to just let it iterate the rest of the list and ignore extra appends. That would still be a lot better than the previous approach (assuming that the performance concerns are real).

by list length

This could be addressed by a function from List<T> to List<String> (or Stream<T> to Stream<String>) that converts each element to a string until hitting the limit, then tacks on "..." if there were any left.

in general

I don't know what hacktoberfest is, but I have to be honest that Guava would be a frustrating project to try to contribute to in that kind of way. We're very guarded about the API surface area, and it's been at a stable size for a while. Statistically, it's inevitable after 12 years that most ideas we hear for improvements are ones that we've gotten before and turned down for $reasons. So yeah, trying to contribute to it tends to breed frustration. Its purpose in the world is more about what it can contribute to you.

Thanks a lot for the response. I'll not continue on this one then and see where else I can contribute 👍

For now, we think the workarounds should be okay; feel free to add more comments though.