import java.util.Arrays;
import java.util.Optional;
import java.util.SortedSet;
import java.util.TreeSet;
public class Main {
public static void main
(final String[] args
) { final SortedSet<String> set = new TreeSet<>();
set.
addAll(Arrays.
asList("foo",
"bar",
"baz",
"bip"));
for (int i = 0; i <= 4; ++i) {
final String prefix
= "bark".
substring(0, i
); System.
out.
printf("Strings starting with %-7s %s%n",
"\"" + prefix
+ "\":",
getElementsWithPrefix(set, prefix));
}
}
/**
* @param prefix
* @return The least string that's greater than all strings starting with
* prefix, if one exists. Otherwise, returns Optional.empty().
* (Specifically, returns Optional.empty() if the prefix is the
* empty string, or is just a sequence of Character.MAX_VALUE-s.)
*/
private static Optional
<String
> incrementPrefix
(final String prefix
) { final StringBuilder sb = new StringBuilder(prefix);
// remove any trailing occurrences of Character.MAX_VALUE:
while (sb.
length() > 0 && sb.
charAt(sb.
length() - 1) == Character.
MAX_VALUE) { sb.setLength(sb.length() - 1);
}
// if the prefix is empty, then there's no upper bound:
if (sb.length() == 0) {
return Optional.empty();
}
// otherwise, increment the last character and return the result:
sb.setCharAt(sb.length() - 1, (char) (sb.charAt(sb.length() - 1) + 1));
return Optional.of(sb.toString());
}
/**
* @param allElements - a SortedSet of strings. This set must use the
* natural string ordering; otherwise this method
* may not behave as intended.
* @param prefix
* @return The subset of allElements containing the strings that start
* with prefix.
*/
private static SortedSet<String> getElementsWithPrefix(
final SortedSet
<String
> allElements,
final String prefix
) {
final Optional<String> endpoint = incrementPrefix(prefix);
if (endpoint.isPresent()) {
return allElements.subSet(prefix, endpoint.get());
} else {
return allElements.tailSet(prefix);
}
}
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuT3B0aW9uYWw7CmltcG9ydCBqYXZhLnV0aWwuU29ydGVkU2V0OwppbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CgpwdWJsaWMgY2xhc3MgTWFpbiB7CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oZmluYWwgU3RyaW5nW10gYXJncykgewogICAgICAgIGZpbmFsIFNvcnRlZFNldDxTdHJpbmc+IHNldCA9IG5ldyBUcmVlU2V0PD4oKTsKICAgICAgICBzZXQuYWRkQWxsKEFycmF5cy5hc0xpc3QoImZvbyIsICJiYXIiLCAiYmF6IiwgImJpcCIpKTsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gNDsgKytpKSB7CiAgICAgICAgICAgIGZpbmFsIFN0cmluZyBwcmVmaXggPSAiYmFyayIuc3Vic3RyaW5nKDAsIGkpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50ZigiU3RyaW5ncyBzdGFydGluZyB3aXRoICUtN3MgJXMlbiIsICJcIiIgKyBwcmVmaXggKyAiXCI6IiwKICAgICAgICAgICAgICAgICAgICBnZXRFbGVtZW50c1dpdGhQcmVmaXgoc2V0LCBwcmVmaXgpKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gcHJlZml4CiAgICAgKiBAcmV0dXJuIFRoZSBsZWFzdCBzdHJpbmcgdGhhdCdzIGdyZWF0ZXIgdGhhbiBhbGwgc3RyaW5ncyBzdGFydGluZyB3aXRoCiAgICAgKiAgICAgICAgIHByZWZpeCwgaWYgb25lIGV4aXN0cy4gT3RoZXJ3aXNlLCByZXR1cm5zIE9wdGlvbmFsLmVtcHR5KCkuCiAgICAgKiAgICAgICAgIChTcGVjaWZpY2FsbHksIHJldHVybnMgT3B0aW9uYWwuZW1wdHkoKSBpZiB0aGUgcHJlZml4IGlzIHRoZQogICAgICogICAgICAgICBlbXB0eSBzdHJpbmcsIG9yIGlzIGp1c3QgYSBzZXF1ZW5jZSBvZiBDaGFyYWN0ZXIuTUFYX1ZBTFVFLXMuKQogICAgICovCiAgICBwcml2YXRlIHN0YXRpYyBPcHRpb25hbDxTdHJpbmc+IGluY3JlbWVudFByZWZpeChmaW5hbCBTdHJpbmcgcHJlZml4KSB7CiAgICAgICAgZmluYWwgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKHByZWZpeCk7CgogICAgICAgIC8vIHJlbW92ZSBhbnkgdHJhaWxpbmcgb2NjdXJyZW5jZXMgb2YgQ2hhcmFjdGVyLk1BWF9WQUxVRToKICAgICAgICB3aGlsZSAoc2IubGVuZ3RoKCkgPiAwICYmIHNiLmNoYXJBdChzYi5sZW5ndGgoKSAtIDEpID09IENoYXJhY3Rlci5NQVhfVkFMVUUpIHsKICAgICAgICAgICAgc2Iuc2V0TGVuZ3RoKHNiLmxlbmd0aCgpIC0gMSk7CiAgICAgICAgfQoKICAgICAgICAvLyBpZiB0aGUgcHJlZml4IGlzIGVtcHR5LCB0aGVuIHRoZXJlJ3Mgbm8gdXBwZXIgYm91bmQ6CiAgICAgICAgaWYgKHNiLmxlbmd0aCgpID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIE9wdGlvbmFsLmVtcHR5KCk7CiAgICAgICAgfQoKICAgICAgICAvLyBvdGhlcndpc2UsIGluY3JlbWVudCB0aGUgbGFzdCBjaGFyYWN0ZXIgYW5kIHJldHVybiB0aGUgcmVzdWx0OgogICAgICAgIHNiLnNldENoYXJBdChzYi5sZW5ndGgoKSAtIDEsIChjaGFyKSAoc2IuY2hhckF0KHNiLmxlbmd0aCgpIC0gMSkgKyAxKSk7CiAgICAgICAgcmV0dXJuIE9wdGlvbmFsLm9mKHNiLnRvU3RyaW5nKCkpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIGFsbEVsZW1lbnRzIC0gYSBTb3J0ZWRTZXQgb2Ygc3RyaW5ncy4gVGhpcyBzZXQgbXVzdCB1c2UgdGhlCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBuYXR1cmFsIHN0cmluZyBvcmRlcmluZzsgb3RoZXJ3aXNlIHRoaXMgbWV0aG9kCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICBtYXkgbm90IGJlaGF2ZSBhcyBpbnRlbmRlZC4KICAgICAqIEBwYXJhbSBwcmVmaXgKICAgICAqIEByZXR1cm4gVGhlIHN1YnNldCBvZiBhbGxFbGVtZW50cyBjb250YWluaW5nIHRoZSBzdHJpbmdzIHRoYXQgc3RhcnQKICAgICAqICAgICAgICAgd2l0aCBwcmVmaXguCiAgICAgKi8KICAgIHByaXZhdGUgc3RhdGljIFNvcnRlZFNldDxTdHJpbmc+IGdldEVsZW1lbnRzV2l0aFByZWZpeCgKICAgICAgICAgICAgZmluYWwgU29ydGVkU2V0PFN0cmluZz4gYWxsRWxlbWVudHMsIGZpbmFsIFN0cmluZyBwcmVmaXgpIHsKCiAgICAgICAgZmluYWwgT3B0aW9uYWw8U3RyaW5nPiBlbmRwb2ludCA9IGluY3JlbWVudFByZWZpeChwcmVmaXgpOwoKICAgICAgICBpZiAoZW5kcG9pbnQuaXNQcmVzZW50KCkpIHsKICAgICAgICAgICAgcmV0dXJuIGFsbEVsZW1lbnRzLnN1YlNldChwcmVmaXgsIGVuZHBvaW50LmdldCgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gYWxsRWxlbWVudHMudGFpbFNldChwcmVmaXgpOwogICAgICAgIH0KICAgIH0KfQ==