I have a code like:
projsForWhichPermCheckFailedSBuilder.append(currentProject.getDisplayString()).append(", ");
This is dynamic append and above code is in for loop... so at last I want to remove extra ", ", I have done something like:
projsForWhichPermCheckFailedString = projsForWhichPermCheckFailedSBuilder.substring(0, projsForWhichPermCheckFailedSBuilder.length()-2);
Please suggest some better way!!! Thanks...
I'm not sure what your input looks like, but let's say for the sake of an example, the input is a collection of String objects, e.g. List<String> input and given:
final String delimiter = ",";
then you could use one of the following approaches ...
Using Java StringBuilder class.
StringBuilder sb = new StringBuilder();
for (String s : input)
{
sb.append("s").append(delimiter);
}
if (sb.toString().endsWith(delimiter))
{
sb.deleteCharAt(sb.length()-1);
}
System.out.println(sb.toString());
// Results in output: s,s,s
Using Guava (see Strings Explained for a full example).
List<String> input = new ArrayList<>();
input.add("1");
input.add("2");
input.add("3");
final String result = Joiner.on(delimiter).join(input);
System.out.println(result);
// Results in output: 1,2,3
Related
I have a small program that iterates over an array of strings and then prints either true or false depending whether the string from array is included into another string.
How to rewrite this program using Stream API methods, such as filter and map?
String mainString = new String ("qrfghjtysd");
String container = new String ("qre fgh ty np");
String[] smallStrings = container.split("\\s++");
StringBuilder res = new StringBuilder();
Arrays.stream(smallStrings). forEach(str -> {
if (mainString.contains(str)) {
res.append("true" + System.lineSeparator());
}
else {
res.append("false" + System.lineSeparator());
}
});
System.out.println(res);
It seems like you want to transform each string s in the array to either "true" or "false" depending on mainString.contains(s), and then join them together with new lines as the separator. The transformation can be done with a map, and the joining can be done with the joining collector.
String res = Arrays.stream(smallStrings)
.map(s -> Boolean.toString(mainString.contains(s)))
.collect(Collectors.joining(System.lineSeparator(), "", System.lineSeparator()));
Like your original code, this adds a trailing new line to the resulting string. If you don't care about the trailing new line, you can just pass a single System.lineSeparator() argument to the joining collector, calling the other overload.
I would suggest something like this:
final String mainString = "qrfghjtysd";
final String container = "qre fgh ty np";
final String res = Arrays.stream(container.split("\\s++"))
.map(mainString::contains)
.map(String::valueOf)
.collect(Collectors.joining(System.lineSeparator()));
System.out.println(res);
String mainString = new String ("qrfghjtysd");
String container = new String ("qre fgh ty np");
String[] smallStrings = container.split("\\s++");
StringBuilder res = new StringBuilder();
Arrays.stream(smallStrings).map(str -> mainString.contains(str)).forEach(flag -> res.append(flag + System.lineSeparator()));
System.out.println(res);
try use "anyMatch":
String mainString = new String ("qrfghjtysd");
String container = new String ("qre fgh ty np");
boolean result = Arrays.stream(container.split("\\s++"))
.anyMatch(s -> s.equals(mainString));
I have a below string which I want to split by ',' only and also want to separate 3rd index which is (1005,111222) of each line .
1002,USD,04/09/2019,1005,1,cref,,,,,,,,,
1001,USD,11/04/2018,111222,10,reftpt001,SHA,Remittance Code,BCITIT31745,,,RTGS,,,,
I am using code down below :
List<String> elements = new ArrayList<String>();
List<String> elements2 = new ArrayList<String>();
StringTokenizer st = new StringTokenizer((String) object);
while(st.hasMoreTokens()) {
String[] row = st.nextToken().split(",");
if (row.length == 5) {
elements.add(row[3]);
}
if (row.length == 12) {
elements2.add(row[3]);
}
}
In the above string, There is a space between 'Remittance Code' but it is splitting till remittance and after that, it counts the code a new line or string. Please advise how can I skip the white space as it is.
There is no apparent need for StringTokenizer here, and the nextToken() call stops at the first space. Instead I suggest calling output.split(",") directly like
String[] row = ((String) object).split("\\s*,\\s*", -1);
And remove the StringTokenizer, note the JavaDoc explicitly says StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
First you can split with, and then use trim operation
String stringToSplit= "1001,ZAR,11/04/2018,111222,10,reftpt001,SHA,Remittance Code,BCITIT31745,,,RTGS,,,,";
StringTokenizer tokenizer = new StringTokenizer(stringToSplit, ",");
while (tokenizer.hasMoreTokens()) { System.out.println(tokenizer.nextToken()); }
Output :
1001 ZAR 11/04/2018 111222 10 reftpt001 SHA Remittance Code
BCITIT31745 RTGS
I tried with this code:
1st approach :
String str = "1001,ZAR,11/04/2018,111222,10,reftpt001,SHA,Remittance Code,BCITIT31745";
String[] words = str.split(",");
for(String word : words) {
System.out.println(word);
}
2nd approach :
String str = "1001,ZAR,11/04/2018,111222,10,reftpt001,SHA,Remittance Code,BCITIT31745";
StringTokenizer tokenizer = new StringTokenizer(str, ",");
while(tokenizer.hasMoreTokens())
{
System.out.println(tokenizer.nextToken());
}
Output :
11/04/2018
111222
10
reftpt001
SHA
Remittance Code
BCITIT31745
Hope this helps you. :)
Assume that I have a list of Strings.
List<String> s = new ArrayList<>();
s.add("one");
s.add("two");
s.add("three");
When I use StringUtils.join(",", s) it gives me the result as
"one, two, three"
Whereas I need the output as
"one","two","three"
We don't like to use Guava utility as the project is not in active state.
Is it possible via Apache Commons utility?
How can I achieve this via utility instead of writing my own logic to do the same?
You can do it in two steps with StringUtils only,
List<String> s = new ArrayList<>();
s.add("one");
s.add("two");
s.add("three");
String step1 = StringUtils.join(s, "\", \"");// Join with ", "
String step2 = StringUtils.wrap(step1, "\"");// Wrap step1 with "
System.out.println(step2);
Output,
"one", "two", "three"
BUT
I need to pass them in a mongo DB query when using $in operator
For mongodb query you don't need to build it this way, specifically in case of $in you can query documents in following way,
BasicDBObject yourInQuery = new BasicDBObject();
yourInQuery.put("in_column", new BasicDBObject("$in", yourList));
DBCursor cursor = collection.find(yourInQuery);
Please read more about this in following link,
Find or Query Data with Java Driver
String joined = s.stream()
.map(plain -> '"' + StringEscapeUtils.escapeJava(plain) + '"')
.collect(Collectors.joining(", "));
The idea is to first convert each of the strings to a properly quoted representation and then join them.
You have to decide for yourself which escaping function to use. And just in case you are generating a CSV file, you should really use some CsvWriter class.
Simply by using join:
Docs example:
String message = String.join("-", "Java", "is", "cool");
// message returned is: "Java-is-cool"
You can do something like:
List<String> list = Arrays.asList("one", "two", "three");
res = String.join(",", list).replaceAll("([^,]+)", "\"$1\"");
replaceAll accepts a regex that catches everything that's not "," (your delimiter), and surrounds it with double quotes.
If your input contains a comma, you can first iterate on the arraylist and add quotes to each element, and only then use join.
You can solve it using Java 8 without any third-party utility.
String csvWithQuotes = s.stream().collect(Collectors.joining("\",\"", "\"", "\""));
The logic used here is to use "," as the separator and then prefix and suffix it with quotes.
Combining the first two answers:
var s = new ArrayList<String>();
s.add("one");
s.add("two");
s.add("three");
var resultString = s.stream()
.map(s -> StringUtils.wrap(s, "\"")
.collect(Collectors.joining(", "));
Note: this uses Java 8 and apache commons.
The old way..put this utility method ,
private static final String DOUBLE_QUOTE_ESCAPED = "\"";
public static final String SYMBOL_COMMA = ",";
public static String joinWithDoubleQuotedElements(List<String> s, String joinSymbol) {
StringBuilder builder = new StringBuilder();
int count = 1;
for (String val : s) {
builder.append(DOUBLE_QUOTE_ESCAPED).append(val).append(DOUBLE_QUOTE_ESCAPED);
if (count != s.size()) {
builder.append(joinSymbol);
}
++count;
}
return builder.toString();
}
Call to joinWithDoubleQuotedElements(s, SYMBOL_COMMA) will give you desired result.
I want to iterate through an array and only add the string to the new string if certain conditions are matched, and then seperate with a comma. IF I could use java 8 it would look like this:
StringJoiner col = new StringJoiner(",");
StringJoiner val = new StringJoiner(",");
//First Iteration: Create the Statement
for(String c : columns) {
//Your PDF has a matching formfield
if(pdf.hasKey(c)) {
col.add(c);
val.add("?");
}
}
However I am stuck on 7. Guava and some of the other libs all seem to take an array/map as input, as opposed to adding via a "add" method.
Whats some Java 7 compatiable code that would acheive the same thing?
Cheers
AL
StringBuilder can do it just fine:
StringBuilder col = new StringBuilder();
StringBuilder val = new StringBuilder();
String separator = "";
for (String c : columns) {
if (pdf.hasKey(c)) {
col.append(separator).append(c);
val.append(separator).append("?");
separator = ",";
}
}
You can use google guava library's Joiner:
private static String reduce(List<String> values) {
return Joiner.on(",").skipNulls().join(values);
}
I have a text file which contains data seperated by '|'. I need to get each field(seperated by '|') and process it. The text file can be shown as below :
ABC|DEF||FGHT
I am using string tokenizer(JDK 1.4) for getting each field value. Now the problem is, I should get an empty string after DEF.However, I am not getting the empty space between DEF & FGHT.
My result should be - ABC,DEF,"",FGHT but I am getting ABC,DEF,FGHT
From StringTokenizer documentation :
StringTokenizer is a legacy class that
is retained for compatibility reasons
although its use is discouraged in new
code. It is recommended that anyone
seeking this functionality use the
split method of String or the
java.util.regex package instead.
The following code should work :
String s = "ABC|DEF||FGHT";
String[] r = s.split("\\|");
Use the returnDelims flag and check two subsequent occurrences of the delimiter:
String str = "ABC|DEF||FGHT";
String delim = "|";
StringTokenizer tok = new StringTokenizer(str, delim, true);
boolean expectDelim = false;
while (tok.hasMoreTokens()) {
String token = tok.nextToken();
if (delim.equals(token)) {
if (expectDelim) {
expectDelim = false;
continue;
} else {
// unexpected delim means empty token
token = null;
}
}
System.out.println(token);
expectDelim = true;
}
this prints
ABC
DEF
null
FGHT
The API isn't pretty and therefore considered legacy (i.e. "almost obsolete"). Use it only with where pattern matching is too expensive (which should only be the case for extremely long strings) or where an API expects an Enumeration.
In case you switch to String.split(String), make sure to quote the delimiter. Either manually ("\\|") or automatically using string.split(Pattern.quote(delim));
StringTokenizer ignores empty elements. Consider using String.split, which is also available in 1.4.
From the javadocs:
StringTokenizer is a legacy class that
is retained for compatibility reasons
although its use is discouraged in new
code. It is recommended that anyone
seeking this functionality use the
split method of String or the
java.util.regex package instead.
you can use the constructor that takes an extra 'returnDelims' boolean, and pass true to it.
this way you will receive the delimiters, which will allow you to detect this condition.
alternatively you can just implement your own string tokenizer that does what you need, it's not that hard.
Here is another way to solve this problem
String str = "ABC|DEF||FGHT";
StringTokenizer s = new StringTokenizer(str,"|",true);
String currentToken="",previousToken="";
while(s.hasMoreTokens())
{
//Get the current token from the tokenize strings
currentToken = s.nextToken();
//Check for the empty token in between ||
if(currentToken.equals("|") && previousToken.equals("|"))
{
//We denote the empty token so we print null on the screen
System.out.println("null");
}
else
{
//We only print the tokens except delimiters
if(!currentToken.equals("|"))
System.out.println(currentToken);
}
previousToken = currentToken;
}
Here is a way to split a string into tokens (a token is one or more letters)
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
s = s.replaceAll("[^A-Za-z]", " ");
StringTokenizer arr = new StringTokenizer(s, " ");
int n = arr.countTokens();
System.out.println(n);
while(arr.hasMoreTokens()){
System.out.println(arr.nextToken());
}
scan.close();
}
package com.java.String;
import java.util.StringTokenizer;
public class StringWordReverse {
public static void main(String[] kam) {
String s;
String sReversed = "";
System.out.println("Enter a string to reverse");
s = "THIS IS ASHIK SKLAB";
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
sReversed = st.nextToken() + " " + sReversed;
}
System.out.println("Original string is : " + s);
System.out.println("Reversed string is : " + sReversed);
}
}
Output:
Enter a string to reverse
Original string is : THIS IS ASHIK SKLAB
Reversed string is : SKLAB ASHIK IS THIS