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);
}
Related
This question already has answers here:
Most efficient way to use replace multiple words in a string [duplicate]
(4 answers)
Closed 5 years ago.
I want to do something like this: Replace all ck with k and all dd with wr and all f with m and 10 more replacements like this.
I can do it with replace("ck","k").replace("dd","wr")and so on, but it seams silly and it is slow. Is there any function in java that does something like this?
for example replace(string,stringArray1, stringArray2);
Use an appendReplacement loop.
Here is a general purpose way to do it:
private static String replace(String input, Map<String, String> mappings) {
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile(toRegex(mappings.keySet())).matcher(input);
while (m.find())
m.appendReplacement(buf, Matcher.quoteReplacement(mappings.get(m.group())));
return m.appendTail(buf).toString();
}
private static String toRegex(Collection<String> keys) {
return keys.stream().map(Pattern::quote).collect(Collectors.joining("|"));
}
If you're not using Java 8+, the second method would be:
private static String toRegex(Collection<String> keys) {
StringBuilder regex = new StringBuilder();
for (String key : keys) {
if (regex.length() != 0)
regex.append("|");
regex.append(Pattern.quote(key));
}
return regex.toString();
}
Test code
Map<String, String> mappings = new HashMap<>();
mappings.put("ck","k");
mappings.put("dd","wr");
mappings.put("f", "m");
System.out.println(replace("odd flock", mappings)); // prints: owr mlok
See IDEONE for running version.
Map<String, String> replacementMap = new HashMap<String, String>();
replacementMap.put("ck", "k");
replacementMap.put("dd", "wr");
replacementMap.put("f", "m");
// ...
String resultStr = "Abck fdddk wr fmck"; // whatever string to process
StringBuilder builder = new StringBuilder(resultStr); // wrap it in builder
Iterator<String> iterator = replacementMap.keySet().iterator();
while (iterator.hasNext()) {
String strToReplace = iterator.next();
replaceAll(builder, strToReplace, replacementMap.get(strToReplace));
}
System.out.println("Result is: " + builder.toString());
public static void replaceAll(StringBuilder builder, String from, String to) {
int index = builder.indexOf(from);
while (index != -1) {
builder.replace(index, index + from.length(), to);
index += to.length(); // Move to the end of the replacement
index = builder.indexOf(from, index);
}
}
The replaceAll() method was borrowed from this Jon Skeet's answer
Alternative to replaceAll() int his example is to use apache commons library, there is StrBuilder class which provides replaceAll() method. see this answer
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
Im trying to rebuild a string using StringBuilder. I'm a little unsure of which method to use to get the "'," inserted back into the same place. In the code below I'm using the
"insert(int dstOffset, CharSequence s, int start, int end)" method. My code doesn't contain any errors however it doesn't run properly.
Please note I will also be escaping characters (i.e., =) in the string but I havent written that part of the code yet. Currently I'm trying to learn how to split the string and then rebuild it.
Thanks
public class StringTestProgram
{
public static void main(String[] args)
{
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
for (String stringoutput : stringData)
{
System.out.print(stringoutput);
StringBuilder sb = new StringBuilder(stringoutput);
CharSequence charAdded = ",";
sb.insert(6,charAdded,0,12);
System.out.print(sb.toString());
}
}
}
Revised code
public class StringTestProgram {
public static void main(String[] args) {
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
System.out.println(relativeDN);
//Split String
String[] stringData = relativeDN.split(",");
{
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
// loop thru each element of the array
for (int place = 0; place < stringData.length; place++) {
System.out.println(stringData[place]);
{
int eq = relativeDN.indexOf('=');
String sub = relativeDN.substring(0, eq);
System.out.println(sub);
}
// append element to the StringBuilder
sb.append(stringData[place]);
// avoids adding an extra ',' at the end
if (place < stringData.length - 1)
// if not at the last element, add the ',' character
sb.append(charAdded);
}
System.out.print(sb.toString());
}
}
}
Im new to stackoverflow and I'm not sure if its ok to ask this question in this thread or if I should create a seperate thread for this question. If possible please advise.
The code above now splits the string at the "," character. It also rebuilds the
string back to its original state. I would also like to use the indexof and .substring
methods to get the string value after the "=" sign. Currently my program only outputs
the first two characters of the initial string value before the "=" sign. Not sure where
in my code I'm making an error. Any help would be appreciated.
My Current Output
cn=abc,dn=xyz,ou=abc/def
cn=abc
cn
dn=xyz
cn
ou=abc/def
cn
cn=abc,dn=xyz,ou=abc/def
Desired Output
cn=abc,dn=xyz,ou=abc/def
cn=abc
abc
dn=xyz
xyz
ou=abc/def
abc/def
cn=abc,dn=xyz,ou=abc/def
The easiest way to do this pre Java 8 is to use 1 StringBuilder for all the elements and add Strings to the builder by using the append() method
StringBuilder builder = new StringBuilder();
for (String stringoutput : stringData) {
builder.append(stringoutput).append(',');
}
//have an extra trailing comma so remove it
//use length -1 as end coord because it's exclusive
String result = builder.substring(0, builder.length() -1);
If you are using Java 8 you can use the new Stream API and Collectors.joining()
String result = Arrays.stream(relativeDN.split(","))
.collect(Collectors.joining(","));
You're initializing sb every time you enter the loop, meaning that you're disposing of your StringBuilder every time you enter the loop and recreate it with only the next subtring.
Fixed:
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
for (String stringoutput : stringData) {
System.out.print(stringoutput);
sb.append(stringoutput).append(charAdded);
}
sb.setLength(sb.length() - 1);
System.out.print(sb.toString());
Try out this code
public class StringTestProgram {
public static void main(String[] args) {
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
CharSequence charAdded = ",";
for (int i = 0; i < stringData .length; i++) { //walk over each element of the array
System.out.println(stringData[i]);
sb.append(stringData[i]); // append element to the StringBuilder
if (i < stringData.length - 1) //avoids adding an extra ',' at the end
sb.append(charAdded); // if not at the last element, add the ',' character
}
System.out.print(sb.toString());
}
}
Here you will reconstruct the original string exactly as it was (i.e. without adding a trailing ','):
cn=abc,dn=xyz,ou=abc/def
UPDATE: In the for loop I just walk over every element of the array that stores the splitted String and append the elements to the StringBuilder instance one by one. After appending each element I check if we are currently at the last element of the array. If not, I append the ',' character.
Like this:
for (String stringoutput : stringData)
sb.append(stringoutput).append(',');
Fixed: Using this approach, you would have to remove the last ,
String result = sb.toString().substring(0,sb.toString().length()-1);
System.out.println(result);
I noticed in the other answers that there would be an extra comma at the end. You have to use a prefix variable and then change it in the loop so that there won't be an extra comma.
String relativeDN = "cn=abc,dn=xyz,ou=abc/def";
String[] stringData = relativeDN.split(",");
StringBuilder sb = new StringBuilder();
String prefix = "";
for (String element : stringData) {
sb.append(prefix);
prefix=",";
sb.append(element);
}
String output = sb.toString();
Inside the loop the prefix is appended, but on the first time through the loop the prefix is set to empty quotes so that there won't be a comma before the first element. Next prefix is changed to a comma so that in the next turn through the loop a comma will be added after the first element. Lastly, the element is added. This results in the correct output because the comma is added before the element, but only after the first iteration.
I have string with value as ||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||
I am trying to write code which should remove duplicates and return the unique values retaining the demiliters like this ||HelpDesk||IT Staff||Admin||Audit||
My code is using HashSet to remove duplicates but the problem is it is removing delimiters. How can I retain delimiters by removing duplicate values only.
Below is my code after removing duplicates and adding back delimiters. But not sure if there is easy way of doing this.
public static void main(String[] args) {
TestDuplicates testDuplicates = new TestDuplicates();
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList =
new ArrayList<String>();
SplitOperations splitOperations =
new SplitOperations();
splittedStringList =
splitOperations.splitString(bRole);
for (int i = 0; i < splittedStringList.size(); i++) {
HashSet<String> listToSet = new HashSet<String>(splittedStringList);
listWithoutDuplicates = new ArrayList<String>(listToSet);
}
for(int i=0;i<listWithoutDuplicates.size();i++){
noDup = noDup + "||"+listWithoutDuplicates.get(i);
System.out.println(listWithoutDuplicates.get(i));
}
System.out.println("No Duplicate is::"+ noDup+"||");
}
Thanks
You could use a LinkedHashSet to preserve insertion order. Once you splitted the String by "||" just add the delimiters when constructing back the String.
String s = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
Set<String> set = new LinkedHashSet<>(Arrays.asList(s.split(Pattern.quote("||"))));
String noDup = "||";
for(String st : set) {
if(st.isEmpty()) continue;
noDup += st+"||";
}
Or using the new java 8 Stream API :
String noDup = "||"+
Arrays.stream(s.split(Pattern.quote("||")))
.distinct()
.filter(st -> !st.isEmpty()) //we need to remove the empty String produced by the split
.collect(Collectors.joining("||"))+"||";
Both approaches yield the same result (||HelpDesk||IT Staff||Admin||Audit||).
public String removeDublicate () {
String str = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
String split[] = str.split("\\|\\|");
String newStr = "";
for (String s : split) {
if (!s.isEmpty() && !newStr.contains(s)) {
newStr += "||" + s;
}
}
newStr += "||";
return newStr;
}
Something like that? str could be an argument.
Edit #1
If you want to get rid of && !newStr.contains(s) you can use a HashSet<String> instead. I think that is overkill however. .contains(s) will do the trick when the string is small such as this.
This should work, also it will maintain sequence of elements if you want. Note that I have not written code to put delimiters again.
public static void main(String s[]){
String a = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
a = a.replaceAll("\\|\\|",",");
String arr[] = a.split(",");
//linked hash set in case you want to maintain the sequence of elements
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr));
set.remove("");
System.out.println(set);
//Iterate through the set and put your delimiters here again
}
Using Guava lib it's a one liner:
Joiner.on("||").skipNulls(Splitter.on("||").trimResults().split(<target_string>);)
Here is my attempt at it:
import java.util.*;
public class Seperator {
public static void main(String[] args) {
String bRole = "||HelpDesk||IT Staff||IT Staff||Admin||Audit||HelpDesk||";
List<String> listWithoutDuplicates = new ArrayList<String>();
String noDup = "";
List<String> splittedStringList = new ArrayList<String>();
splittedStringList = Arrays.asList(bRole.split("\\|\\|"));
LinkedHashSet<String> listToSet = new LinkedHashSet<String>(splittedStringList);
noDup = Seperator.join(listToSet, "||");
System.out.println("No Duplicate is::"+ noDup+"||");
}
public static String join(Set<String> set, String sep) {
String result = null;
if(set != null) {
StringBuilder sb = new StringBuilder();
Iterator<String> it = set.iterator();
if(it.hasNext()) {
sb.append(it.next());
}
while(it.hasNext()) {
sb.append(sep).append(it.next());
}
result = sb.toString();
}
return result;
}
}
LinkedHashSet are mainly used to preserve the order and ofcourse get uniques elements. Joining is pretty standard, but we can use Google's Guava Library also (Joiner):
So, instead of Seperator.join(listToSet, "||");
You'll have: Joiner.on("||").join(listToSet);
Here's a regex-based one liner:
str = str.replaceAll("(\\|[^|]+)(?=.*\\1\\|)", "");
This works by replacing every term that is followed by itself somewhere ahead via a look ahead assertion that uses a back reference.
Here's a non-regex java 8 one liner:
Arrays.stream(str.substring(1).split("[|]")).distinct().collect(Collectors.joining("|", "|", "|"));
This question already has answers here:
What's the best way to build a string of delimited items in Java?
(37 answers)
Closed 9 years ago.
I have Set<String> result & would like to convert it to comma separated string. My approach would be as shown below, but looking for other opinion as well.
List<String> slist = new ArrayList<String> (result);
StringBuilder rString = new StringBuilder();
Separator sep = new Separator(", ");
//String sep = ", ";
for (String each : slist) {
rString.append(sep).append(each);
}
return rString;
Since Java 8:
String.join(",", slist);
From Apache Commons library:
import org.apache.commons.lang3.StringUtils
Use:
StringUtils.join(slist, ',');
Another similar question and answer here
You could count the total length of the string first, and pass it to the StringBuilder constructor. And you do not need to convert the Set first.
Set<String> abc = new HashSet<String>();
abc.add("A");
abc.add("B");
abc.add("C");
String separator = ", ";
int total = abc.size() * separator.length();
for (String s : abc) {
total += s.length();
}
StringBuilder sb = new StringBuilder(total);
for (String s : abc) {
sb.append(separator).append(s);
}
String result = sb.substring(separator.length()); // remove leading separator
The Separator you are using is a UI component. You would be better using a simple String sep = ", ".