An acronym is a word formed from the initial letters of words in a set phrase. Define a method named createAcronym that takes a string parameter and returns the acronym of the string parameter. Append a period (.) after each letter in the acronym. If a word begins with a lower case letter, don't include that letter in the acronym. Then write a main program that reads a phrase from input, calls createAcronym() with the input phrase as argument, and outputs the returned acronym. Assume the input has at least one upper case letter.
Ex: If the input is:
Institute of Electrical and Electronics Engineers
the output should be:
I.E.E.E.
Ex: If the input is:
Association for computing MACHINERY
the output should be:
A.M.
The letters ACHINERY in MACHINERY don't start a word, so those letters are omitted.
The program must define and call a method:
public static String createAcronym(String userPhrase)
So far my code looks like this:
import java.util.Scanner;
public class LabProgram {
public static String createAcronym(String userPhrase) {
String[] separatedWords = userPhrase.split(" ");
String acronymAlphabets = " ";
for(int i = 0; i < separatedWords.length; ++i) {
if(Character.isUpperCase(separatedWords [i].charAt(0))) {
acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0));
}
}
return acronymAlphabets;
}
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
System.out.println(createAcronym(userInput.nextLine()));
}
}
The system returns the correct acronym but cant for the life of me figure out how to get the periods in the proper place. Side note: Im really good at getting them at the beginning or end of them. Any help "appending" this problem would be awesome!
Change
acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0));
to
acronymAlphabets += Character.toUpperCase(separatedWords [i].charAt(0))+".";
Here is one way using streams.
String[] titles = {"Institute of Electrical and Electronics Engineers",
"Association for Computing MACHINERY",
"Association of Lions, and Tigers, and Bears, oh my!!"};
for (String title : titles) {
System.out.println(createAcronym(title));
}
prints
I.E.E.E
A.C.M
A.L.T.B
Split on anything that isn't a word and stream the array
filter any words not starting with an upper case character.
Map the first letter of each word to a String.
and join together with a period between each word.
public static String createAcronym(String title) {
return Arrays.stream(title.split("\\W+"))
.filter(str -> Character.isUpperCase(str.charAt(0)))
.map(str -> str.substring(0, 1))
.collect(Collectors.joining("."));
}
Here's a solution that will include a starting letter if it is capitalized, and tack on a period (".") after any included letters.
A few comments:
Line 3: a StringBuilder is an efficient, powerful way to make small additions to a String
Line 5: use a "for" loop over the words (from line 2)
Line 6: isolate the starting character of "word"
Line 8: if firstChar is upper case, go ahead and append it to the StringBuilder result (no need to uppercase it again – it is already upper case or we wouldn't have made to line 8); and any time we append a letter, always go ahead and append a ".", too
Line 12: once we're done with all of the words, conver the StringBuilder to a String, and return the result
1. public static String createAcronym(String input) {
2. String[] words = input.split(" ");
3. StringBuilder result = new StringBuilder();
4.
5. for (String word : words) {
6. char firstChar = word.charAt(0);
7. if (Character.isUpperCase(firstChar)) {
8. result.append(firstChar).append(".");
9. }
10. }
11.
12. return result.toString();
13. }
You could further improve this by editing Line 2: instead of calling split() with a single space (" "), you could instead use a regular expressions to split on any number of whitespaces, tabs, etc.
Don't you just need to append a period (.) after each letter.
Add the following line at the end of the loop.
acronymAlphabets += ".";
Footnote: I would say the Answer offered by Kaan above using StringBuilder is better. I have offered an Answer making minimal chances to the code in the question. Given the OP is a novice I believe it's unhelpful to introduce too many new ideas in a reply.
In programming and Java there's usually a dozen ways to do anything. Bombarding novices with new concepts only confuses them. One step at a time if you ask me.
Other Answers, such as the one by WJS, give a direct, correct solution to the specifics of the Question: appending . to each capital letter. My Answer here is more for fun.
tl;dr
Using code points rather than char.
System.out.println(
String.join( // Join a bunch of strings into a single `String` object.
"" , // Join the strings without any delimiter between them.
Arrays.stream( // Turn an array into a stream of elements for processing.
"Association of Lions, and Tigers, and Bears, oh my!!"
.split( " " ) // Returns an array of string objects, `String[]`.
)
.filter( ( String part ) -> ! part.isBlank() ) // Skip any string elements without significant text.
.map( ( String part ) -> part.codePoints().boxed().toList() ) // Generate a stream of `int` integer numbers representing the code point numbers of each character in the string element. Via boxing, convert those `int` primitives into `Integer` objects. Collect the `Integer` objects into a `List`.
.filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) ) // Skip any list of code points if the first code point represents a character other than an uppercase letter.
.map( ( List < Integer > codePoints ) -> Character.toString( codePoints.get( 0 ) ) + "." ) // Extract the first code point `Integer` number, turn into a `String` containing the single character represented by that code point, and append a FULL STOP.
.toList() // Collect all those generated strings (single character plus FULL STOP) to a list.
)
);
A.L.T.B.
Code points
I recommend making a habit of using code point integer numbers rather than the legacy char type. As a 16-bit value, char is physically incapable of representing most characters.
This code makes heavy use of streams. If not yet comfortable with streams, you could replace with conventional loops.
Pull apart the phrase.
System.out.println( "input = " + input );
String[] parts = input.split( " " );
if ( parts.length == 0 ) { throw new IllegalArgumentException( "Input must consist of multiple words separated by spaces." ); }
System.out.println( "parts = " + Arrays.toString( parts ) );
Convert each part of the phrase into code point integer numbers.
List < List < Integer > > codePointsOfEachPart =
Arrays
.stream( parts )
.filter( part -> ! part.isBlank() )
.map( part -> part.codePoints().boxed().toList() )
.toList();
Filter for those parts of the phrase that begin with an uppercase letter. From each of the qualifying parts, extract the first letter, append a FULL STOP, and collect to a list.
List < String > abbreviations =
codePointsOfEachPart
.stream()
.filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
.map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
.toList();
// Join the collection of UppercaseLetter + FULL STOP combos into a single piece of text.
String result = String.join( "" , abbreviations );
return result;
}
When run:
input = Association of Lions, and Tigers, and Bears, oh my!!
parts = [Association, of, , Lions,, and, Tigers,, and, Bears,, oh, my!!]
output = A.L.T.B.
Pull that all together for your copy-paste convenience.
private String acronym ( final String input )
{
// Pull apart the phrase.
System.out.println( "input = " + input );
String[] parts = input.split( " " );
if ( parts.length == 0 ) { throw new IllegalArgumentException( "Input must consist of multiple words separated by spaces." ); }
System.out.println( "parts = " + Arrays.toString( parts ) );
// Convert each part of the phrase into code point integer numbers.
List < List < Integer > > codePointsOfEachPart =
Arrays
.stream( parts )
.filter( part -> ! part.isBlank() )
.map( part -> part.codePoints().boxed().toList() )
.toList();
// Filter for those parts of the phrase that begin with an uppercase letter.
// From each of the qualifying parts, extract the first letter, append a FULL STOP, and collect to a list.
List < String > abbreviations =
codePointsOfEachPart
.stream()
.filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
.map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
.toList();
// Join the collection of UppercaseLetter + FULL STOP combos into a single piece of text.
String result = String.join( "" , abbreviations );
return result;
}
That code could be shortened, into a single line of code! Not that I necessarily recommend doing so.
System.out.println(
String.join(
"" ,
Arrays.stream(
"Association of Lions, and Tigers, and Bears, oh my!!"
.split( " " )
)
.filter( part -> ! part.isBlank() )
.map( part -> part.codePoints().boxed().toList() )
.filter( ( List < Integer > codePoints ) -> Character.isUpperCase( codePoints.get( 0 ) ) )
.map( codePoints -> Character.toString( codePoints.get( 0 ) ) + "." )
.toList()
)
);
A.L.T.B.
Related
I am working on some strings and trying to parse through the data and retrieve a string that lies before the third occurrence of " - " from the end of the string. This data comes as a String from the DB and there is some text "-NONE----" that I would like to exclude while parsing.
Input (Below input is a String and not List)
String input1 = "-A123456-B987-013691-000-109264821"
String input2 = "-NONE----"
String input3 = "C1234567-A1241-EF-012361-000-18273460"
Output
String output1 = "-A123456-B987"
String output2= "-NONE----"
String output3 = "C1234567-A1241-EF"
Starting from the beginning of my string, I need to retrieve data before the third occurrence of
" - " (hyphen) is found, but I need to count " - " (hyphen) occurrence starting from end of string.
Any tips are appreciated.
You could use a regex replacement approach:
String input = "-A123456-B987-013691-000-109264821";
String output = "([^-]*(?:-[^-]+){2}).*", "$1");
System.out.println(output); // -A123456-B987
The regex pattern used here says to match:
( open capture group
[^-]* match optional first term
(?:-[^-]+){2} then match - and a term, twice
) close capture group, available as $1
.* consume the remainder of the string
You could match the three dashes from behind with the $ symbol and then extract everything that is in front of that. I created two capture groups, where the first one is what you want to extract:
private static String extractFront(String input1) {
if(input1.equals("-NONE----")) {
return input1;
} else {
Pattern pattern = Pattern.compile("(.*)(-[^-]*){3}$");
Matcher matcher = pattern.matcher(input1);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
}
Main to test:
public static void main(String[] args) {
String input1 = "-A123456-B987-013691-000-109264821";
String input2 = "-NONE----";
String input3 = "C1234567-A1241-EF-012361-000-18273460";
System.out.println(extractFront(input1));
System.out.println(extractFront(input2));
System.out.println(extractFront(input3));
}
Output:
-A123456-B987
-NONE----
C1234567-A1241-EF
EDIT: #stubbleweb1995 added the if condition for a complete solution
We can use streams, lambdas, and predicate.
Split your input on its end-of-line character, to get an array of strings. We filter out the “NONE” lines.
For each line, we split into pieces, using the hyphen as a delimiter. This gives us an array of strings that we reassemble using only the 3 parts.
Lastly we collect into a list.
Here is some untested code to get you started.
String[] lines = input.split( "\n" ) ;
List < String > results =
Arrays
.stream( lines )
.filter( line -> ! line.contains( "-NONE-" )
.map(
line -> {
String.join(
"-" ,
Arrays.copyOf( line.split( "-" , 4 ) , 3 , String[].class )
)
}
)
.toList()
;
The acronym() method takes an ArrayList<String>, removes the boring words, and returns an acronym as a String.
Example:
ArrayList<String> words = new ArrayList<String>();
words.add("THE");
words.add("UNITED");
words.add("STATES");
words.add("OF");
words.add("AMERICA");
System.out.println(acronym(words)); // Prints "USA" (without the quotes)
I am suppose to write acronym(). Use the boringWords array to filter out words that won’t be in the acronym (“THE”, “AND”, etc.). Assume all Strings are in ALL CAPS to make the code easier.
public static String acronym(ArrayList<String> phrase) {
String[] boringWords = { "THE", "AND", "OR", "OF", "FROM", "TO", "A", "AN" };
ArrayList<String> wordList = (ArrayList<String>) phrase.clone(); //If you choose to use remove(), use wordList, which is a copy of the input parameter
String acronym = ""; // Return this at the end of the method
// First step: Remove all of the boring words.
// Second step: Grab the first letters of wordList and concatenate them into
// the acronym variable.
// Third step: Return the acronym
// YOUR CODE HERE IN RED
}
Any Ideas?
I did it in Java. It might not be efficient though.
public static String acronym(ArrayList<String> phrase) {
String[] boringWords = { "THE", "AND", "OR", "OF", "FROM", "TO", "A", "AN" };
ArrayList<String> wordList = (ArrayList<String>) phrase.clone(); //If you choose to use remove(), use wordList, which is a copy of the input parameter
String acronym = ""; // Return this at the end of the method
Boolean boring = false;
for (String word : phrase) {
boring = false;
for (String boringWord : boringWords) {
if (boringWord == word) {
boring = true;
break;
}
}
if (!boring) {
acronym += word.charAt(0);
}
}
return acronym;
}
Streams
For a different approach, you can use streams.
Define your inputs. You can use List.of to make an unmodifiable List with simple literals syntax.
List < String > boring = List.of( "THE" , "AND" , "OR" , "OF" , "FROM" , "TO" , "A" , "AN" );
List < String > input = List.of( "THE" , "UNITED" , "STATES" , "OF" , "AMERICA" );
We want to process the input as a series of objects, a stream. Do this with a call to List#stream.
Then we weed out the boring words passing a Predicate to the Stream#filter method.
Of the non-boring words that passed our predicate test, we want to extract the first letter. So we use Stream#map to transform each String object word of our input list. We pull the first letter by asking for the code point integer assigned by the Unicode Consortium to the first character in the stream. Beware of solutions using char primitive type — that type is now obsolete, unable to represent even half of the characters defined in Unicode and supported by Java. Instead, learn to work with individual characters as code point integers. After pulling the first code point number, we transform that back into a single-character String object by calling Character.toString.
At this point we have changed our stream of words into a stream of first-characters. We need to pull those together by calling Stream#collect, and passing method references to make a StringBuilder object for appending each of those first characters.
Finally we call StringBuilder#toString to retrieve our acronym as a String object.
Notice how this is technically a single-line of code! Streams pack quite a punch, a lot going on in very few words.
String acronym =
input
.stream()
.filter( word -> ! boring.contains( word ) )
.map( word -> Character.toString( word.codePointAt( 0 ) ) )
.collect( StringBuilder :: new , StringBuilder :: append , StringBuilder :: append )
.toString();
See this code run live at IdeOne.com.
acronym = USA
I have a database that stores strings that people wrote. Those string for example defines the name of movies.
In order to overcome duplicates and some other things, I did that no matter what the user typed, it will make every first letter capital. In that manner, all of the strings will be saved in the same way.
The way I do it is by using:
String[] words = query.split( "\\s+" );
for (int i = 0; i < words.length; i++) {
String Word = words[i].replaceAll( "[^\\w]", "" );
words[i] = Word.substring( 0, 1 ).toUpperCase() + Word.substring( 1 );
}
query = TextUtils.join( " ", words );
However, I faced a problem when I tried to type something like: Tom & Jerry.
In that case, I got an error with the &. Do I just need to set if conditions to check for every letter such as &, (, ), $ and so on?
toUpperCase handles non-letter characters just fine, and just returns the same character. The problem with your code is that it assumes each word is non-empty, which is no longer true after you remove the special characters.
To make a long story short, just keep the special characters, and you should be OK:
for (int i = 0; i < words.length; i++) {
String word = words[i];
words[i] = word.substring( 0, 1 ).toUpperCase() + word.substring( 1 );
}
I'm looking for a way to capture the year and the last number of a string. ex: "01/02/2017,546.12,24.2," My problem so far I only got Found value : 2017 and Found value : null. I'm not able to capture the group(2). Thanks
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
public class Bourse {
public static void main( String args[] ) {
Scanner clavier = new Scanner(System.in);
// String to be scanned to find the pattern.
String line = clavier.nextLine();
String pattern = "(?<=\\/)(\\d{4})|(\\d+(?:\\.\\d{1,2}))(?=,$)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
} else {
System.out.println("NO MATCH");
}
}
}
Try this one:
(\\d{2}\\.?\\d{2})
\\d{2} - exactly two digits
\\.? - optional dot
\\d{2} - exactly two digits
If I understood you correctly you're looking for 4 digits, which could be separated by dot.
Your requirements are not very clear, but this works for me to simply grab the year and the last decimal value:
Pattern pattern = Pattern.compile("[0-9]{2}/[0-9]{2}/([0-9]{4}),[^,]+,([0-9.]+),");
String text = "01/02/2017,546.12,24.2,";
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
String year = matcher.group(1);
String lastDecimal = matcher.group(2);
System.out.println("Year "+year+"; decimal "+lastDecimal);
}
I don't know whether you're deliberately using lookbehind and lookahead, but I think it's simpler to explicitly specify the full date pattern and consume the value between two explicit comma characters. (Obviously if you need the comma to remain in play you can replace the final comma with a lookahead.)
By the way, I'm not a fan of the \d shorthand because in many languages this will match all digit characters from the entire Unicode character space, when usually only matching of ASCII digits 0-9 is desired. (Java does only match ASCII digits when \d is used, but I still think it's a bad habit.)
Parse, not regex
Regex is overkill here.
Just split the string on the comma-delimiter.
String input = "01/02/2017,546.12,24.2,";
String[] parts = input.split( "," );
Parse each element into a meaningful object rather than treating everything as text.
For a date-only value, the modern approach uses the java.time.LocalDate class built into Java 8 and later.
// Parse the first element, a date-only value.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate localDate = null;
String inputDate = parts[ 0 ] ;
try
{
localDate = LocalDate.parse( inputDate , f );
} catch ( DateTimeException e )
{
System.out.println( "ERROR - invalid input for LocalDate: " + parts[ 0 ] );
}
For numbers with decimals where accuracy matters, avoid the floating-point types and instead use BigDecimal. Given your class name “Bourse“, I assume the numbers relate to money, so accuracy matters. Always use BigDecimal for money matters.
// Loop the numbers
List < BigDecimal > numbers = new ArrayList <>( parts.length );
for ( int i = 1 ; i < parts.length ; i++ )
{ // Start index at 1, skipping over the first element (the date) at index 0.
String s = parts[ i ];
if ( null == s )
{
continue;
}
if ( s.isEmpty( ) )
{
continue;
}
BigDecimal bigDecimal = new BigDecimal( parts[ i ] );
numbers.add( bigDecimal );
}
Extract your two desired pieces of information: the year, and the last number.
Consider passing around a Year object in your code rather than a mere integer to represent the year. This gives you type-safety and makes your code more self-documenting.
// Goals: (1) Get the year of the date. (2) Get the last number.
Year year = Year.from( localDate ); // Where possible, use an object rather than a mere integer to represent the year.
int y = localDate.getYear( );
BigDecimal lastNumber = numbers.get( numbers.size( ) - 1 ); // Fetch last element from the List.
Dump to console.
System.out.println("input: " + input );
System.out.println("year.toString(): " + year );
System.out.println("lastNumber.toString(): " + lastNumber );
See this code run live at IdeOne.com.
input: 01/02/2017,546.12,24.2,
year.toString(): 2017
lastNumber.toString(): 24.2
I want to trim a string if the length exceeds 10 characters.
Suppose if the string length is 12 (String s="abcdafghijkl"), then the new trimmed string will contain "abcdefgh..".
How can I achieve this?
s = s.substring(0, Math.min(s.length(), 10));
Using Math.min like this avoids an exception in the case where the string is already shorter than 10.
Notes:
The above does simple trimming. If you actually want to replace the last characters with three dots if the string is too long, use Apache Commons StringUtils.abbreviate; see #H6's solution. If you want to use the Unicode horizontal ellipsis character, see #Basil's solution.
For typical implementations of String, s.substring(0, s.length()) will return s rather than allocating a new String.
This may behave incorrectly1 if your String contains Unicode codepoints outside of the BMP; e.g. Emojis. For a (more complicated) solution that works correctly for all Unicode code-points, see #sibnick's solution.
1 - A Unicode codepoint that is not on plane 0 (the BMP) is represented as a "surrogate pair" (i.e. two char values) in the String. By ignoring this, we might trim the string to fewer than 10 code points, or (worse) truncate it in the middle of a surrogate pair. On the other hand, String.length() is not a good measure of Unicode text length, so trimming based on that property may be the wrong thing to do.
StringUtils.abbreviate from Apache Commons Lang library could be your friend:
StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."
Commons Lang3 even allow to set a custom String as replacement marker. With this you can for example set a single character ellipsis.
StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"
There is a Apache Commons StringUtils function which does this.
s = StringUtils.left(s, 10)
If len characters are not available, or the String is null, the String will be returned without an exception. An empty String is returned if len is negative.
StringUtils.left(null, ) = null
StringUtils.left(, -ve) = ""
StringUtils.left("", *) = ""
StringUtils.left("abc", 0) = ""
StringUtils.left("abc", 2) = "ab"
StringUtils.left("abc", 4) = "abc"
StringUtils.Left JavaDocs
Courtesy:Steeve McCauley
As usual nobody cares about UTF-16 surrogate pairs. See about them: What are the most common non-BMP Unicode characters in actual use? Even authors of org.apache.commons/commons-lang3
You can see difference between correct code and usual code in this sample:
public static void main(String[] args) {
//string with FACE WITH TEARS OF JOY symbol
String s = "abcdafghi\uD83D\uDE02cdefg";
int maxWidth = 10;
System.out.println(s);
//do not care about UTF-16 surrogate pairs
System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
//correctly process UTF-16 surrogate pairs
if(s.length()>maxWidth){
int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
}
}
Or you can just use this method in case you don't have StringUtils on hand:
public static String abbreviateString(String input, int maxLength) {
if (input.length() <= maxLength)
return input;
else
return input.substring(0, maxLength-2) + "..";
}
s = s.length() > 10 ? s.substring(0, 9) : s;
Just in case you are looking for a way to trim and keep the LAST 10 characters of a string.
s = s.substring(Math.max(s.length(),10) - 10);
tl;dr
You seem to be asking for an ellipsis (…) character in the last place, when truncating. Here is a one-liner to manipulate your input string.
String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;
See this code run live at IdeOne.com.
abcdefghi…
Ternary operator
We can make a one-liner by using the ternary operator.
String input = "abcdefghijkl" ;
String output =
( input.length() > 10 ) // If too long…
?
input
.substring( 0 , 10 - 1 ) // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
.concat( "…" ) // Add the ellipsis character.
: // Or, if not too long…
input // Just return original string.
;
See this code run live at IdeOne.com.
abcdefghi…
Java streams
The Java Streams facility makes this interesting, as of Java 9 and later. Interesting, but maybe not the best approach.
We use code points rather than char values. The char type is legacy, and is limited to the a subset of all possible Unicode characters.
String input = "abcdefghijkl" ;
int limit = 10 ;
String output =
input
.codePoints()
.limit( limit )
.collect( // Collect the results of processing each code point.
StringBuilder::new, // Supplier<R> supplier
StringBuilder::appendCodePoint, // ObjIntConsumer<R> accumulator
StringBuilder::append // BiConsumer<R,R> combiner
)
.toString()
;
If we had excess characters truncated, replace the last character with an ellipsis.
if ( input.length () > limit )
{
output = output.substring ( 0 , output.length () - 1 ) + "…";
}
If only I could think of a way to put together the stream line with the "if over limit, do ellipsis" part.
The question is asked on Java, but it was back in 2014.
In case you use Kotlin now, it is as simple as:
yourString.take(10)
Returns a string containing the first n characters from this string, or the entire string if this string is shorter.
Documentation
str==null ? str : str.substring(0, Math.min(str.length(), 10))
or,
str==null ? "" : str.substring(0, Math.min(str.length(), 10))
Works with null.
// this is how you shorten the length of the string with ..
// add following method to your class
private String abbreviate(String s){
if(s.length() <= 10) return s;
return s.substring(0, 8) + ".." ;
}