How to skip a particular string during string Joining in Java? - java

The source code I have uploaded it will join some strings value in a one line. I want a way that I can able to skip a particular string in time of string joining. Here i have stored the strings "This","is","a","test." in a string array. I want that in time of joining a particular string will be skipped. Like I want to skip "a". How can I able to do in Java? I want a generalized way that I will able to apply for any strings.
import java.util.StringJoiner;
public class Test_Joiner_for_seatPlan
{
public static void main(String[] args)
{
StringJoiner joinString = new StringJoiner( " ");
String[] testStringArray = {"This","is","a","test."};
String joinedString = null;
for(String s : testStringArray)
{
joinString.add(s);
}
joinedString = joinString.toString();
System.out.println("After Joining the String:\n"+joinedString);
}
}

Try with not equal condition with string. but its not feasible as its check everytime a value.
for(String s : testStringArray)
{
if(!s.equals("a")){
joinString.add(s);
}
}
If you have a list of values like a,b,c than you can do like this:
Set<String> exclude = new HashSet<String>(Arrays.asList("a","b","c"));
for(String s : testStringArray)
{
if(!exclude.contains(s)){
joinString.add(s);
}
}

Use Split method of string. It returns array. combine each of them to get the string.
for (String retval: Str.split("a")){
System.out.println(retval);
}

You can do it like this:
Code:
for(String s : testStringArray){
if(!s.equals("a")){ // replace 'a' with the required character or word you want to ignore
joinString.add(s);
}
}

One possible solution is to provide a Map or a List in which you store the String values that should get excluded in your join. Here is an example using a Map.
public static void main(String[] args) {
String[] testStringArray = {"This","is","a","test."};
Map<String, String> excludedStrings = createExcludingMap("a");
System.out.println("After Joining the String:\n" + join(testStringArray, excludedStrings));
}
private static String join(String[] inputData, Map<String, String> excludedStrings){
StringJoiner joinString = new StringJoiner( " ");
String joinedString = null;
for(String s : inputData)
{
if(excludedStrings.get(s) == null) // IF this return null, the String is not part of the Strings to be excluded, hence join the string
joinString.add(s);
}
joinedString = joinString.toString();
return joinString.toString();
}
private static Map<String, String> createExcludingMap(String... values) {
Map<String, String> output = new HashMap<>();
for(String s : values) { // Add each value to the map, with s as key
output.put(s, s);
}
return output;
}
output :/
After Joining the String:
This is test.

The StringJoiner is a utility class that was written specifically to be used with the new Java8 Stream functionality. The documentation of StringJoiner also refers to the Collectors.joining method. It creates the StringJoiner, and wraps it in an object suitable to pass to Stream.collect, actually a Collector.
As part of the Stream API we now also have direct support for filters, it is just a matter of employing the fluent API (fluent because we keep adding .something(...)) to add the .filter method.
You can use it as you did in your answer, but I would suggest doing it as follows:
import static java.util.stream.Collectors.joining;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class App {
public static String joinString(String [] sa,Predicate<String> filter) {
return Stream.of(sa).filter(filter).collect(joining(" "));
}
public static void main(String[] args) {
String[] testStringArray = new String [] {"This","is","a","test."};
System.out.println(joinString(testStringArray,(s)->!s.equals("a")));
}
}
I have deliberately broken it up by defining an extra method, so you can see the type of the filter passed along, exposing the Predicate. This would also make your function a little more generic making it work as you stated: 'I want a generalized way that I will able to apply for any strings'.
However if the Stream api is flexible enough that I do not see any need to abstract your own API for it. I suggest using it as-is:
import static java.util.stream.Collectors.joining;
import java.util.stream.Stream;
public class App {
public static void main(String[] args) {
System.out.println(
Stream
.of(new String [] {"This","is","a","test."})
.filter((s)->!s.equals("a"))
.collect(joining(" "))
);
}
}
I could have written most of it on a single line, but I like to break it up for readability.

Related

Split Java List items within String

The code example below shows a Test class that is supposed to print the list out as follows:
'A','B','C' (note the quotation marks).
Is there a method I can use to do that kind of formatting directly within the String assignment?
public class TEST {
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("A");
test.add("B");
test.add("C");
System.out.println(test);
System.out.println("Expected: 'A','B','C'"); // wanted output
}
}
Output:
[A, B, C]
Expected: 'A','B','C'
One option to print the desired result would be to use String.join in System.out.format:
public static void main(String[] args) {
List<String> test = new ArrayList<>();
test.add("A");
test.add("B");
test.add("C");
System.out.format("'%s'", String.join("','", test));
}
This code produces the following output:
'A','B','C'
Applying this format directly within the String assignment can be done in a similar way, by combining String.format and String.join:
String formatted = String.format("'%s'", String.join("','", test));
You can use any of a variety of methods to do the conversion. You can then use your favorite method in a lambda like so. Here I am using deHaar's solution.
Function<List<String>, String> format = lst-> String.format("'%s'",
String.join("','", lst));
String result = format.apply(myList);
A somewhat more extreme solution is to create a method that returns an ArrayList with the toString method overridden. Unless you create a lot of lists of varying types and don't want to have to reformat the list, it is probably overkill. But it demonstrates a technique.
List<String> listString = createList(List.of("A","B","C"));
List<Integer> listInt = createList(List.of(1,2,3,4));
System.out.println(listString);
System.out.println(listInt);
prints
'A','B','C'
'1','2','3','4'
A single no arg method could be used and then the list populated. I added a helper to permit passing a Collection to populate the list upon creation.
the no arg method calls the the other with an empty list.
the single arg method simply returns an instance of the ArrayList with populated with the supplied collection and overriding the toString() method.
#SuppressWarnings("unchecked")
public static <T> List<T> createList() {
return createList(Collections.EMPTY_LIST);
}
public static <T> List<T> createList(Collection<T> list) {
return new ArrayList<T>(list) {
#Override
public String toString() {
return stream().map(s -> s + "")
.collect(Collectors.joining("','", "'", "'"));
}
};
}

Java construrctor with string params

How can I extract attributes values from the string parameter ?
public class Pays{
public Pays(String paysDescriptions) {
//implementation
}
}
pays= new Pays("p1:Europe:France, p2:Amerique:Canada");
Edit:
I gave an answer below to people who have never used this type of constructor (like me :p ) and who may need some explanations.
You should try using String.split(String regex) API.
Break the parameter paysDescriptions using comma(,) as regex, then
Break the individual items using colon(:) as regex
Example:
public Pays(String paysDescriptions) {
String[] split_1 = paysDescriptions.split(",");
for (String split : split_1) {
String[] split_2 = split.split(":");
for (String sp : split_2) {
System.out.println(sp); // use sp.trim() if spaces after comma
// not required.
}
}
}
I misunderstand the logic because it's the first time I saw this kind of conctructor..I have only the unit test class and I should implement the code for the source one. So I've used a Map<String,String[]> to split parameters and then I can access to the various attributes of my class.
Map<String, String[]> paysMap = new HashMap<String, String[]>();
public Pays(String paysDescriptions) {
String s = paysDescriptions;
String[] pairs = s.split(",");
for (int i=0;i<pairs.length;i++) {
String pair = pairs[i];
String[] keyValue = pair.split(":");
paysMap.put(String.valueOf(keyValue[0]),new String[] {String.valueOf(keyValue[1]), String.valueOf(keyValue[2])});
}
}

How to sort this string and rebuild the same sorted string again

How can I sort values in this string based on the integral parts i.e.
Input:
[160,190];[650,790];[901,974];[401,540];[60,90];
O/p:
[60,90];[160,190];[401,540];[650,790];[901,974];
Obviously a regular sort must do in this case but I am not sure about
where should I trim the strings compare and rebuild the exact string
with optimized approach.
I'd implement the Comparator interface; a class holding both values of a pair and then:
parse the string using ';' as delimeter and put it in holder class
put all of the holder objects into a List
sort the list using the implemented comparator
Using Guava instead of reimplementing most of the necessary steps.
The first part, parsing the string and converting it to a list of integers will be much nicer, once Lambda expressions can be used.
import static com.google.common.base.CharMatcher.anyOf;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
import java.util.Collections;
import java.util.List;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
public class StrangeSort {
public static void main(String[] args) {
String input = "[160,190];[650,790];[901,974];[401,540];[60,90]";
Splitter splitter = Splitter.on(anyOf("[],;")).omitEmptyStrings();
// This will be so much nicer with Lambda Expressions
List<Integer> list = newArrayList(transform(newArrayList(splitter.split(input)),
new Function<String, Integer>() {
#Override
public Integer apply(String arg0) {
return Integer.valueOf(arg0);
}}));
// Sort the list
Collections.sort(list);
// Print the list
String output = Joiner.on(';').join(Iterables.partition(list, 2));
System.out.println(output);
}
}
If you need to get rid of the whitespace in the output, you can print output.replaceAll(" ", "");
If each [] specifies a unique range of values, you can extract all numbers, sort them and then construct the resultant string back by grouping two elements in each [].
Pattern pattern = Pattern.compile("(\\d+)");
Matcher matcher = pattern.matcher(s);
Set<Integer> numbers = new TreeSet<>();
while(matcher.find()) {
numbers.add(Integer.parseInt(matcher.group(1)));
}
Next step would be to iterate over numbers and use the current and next index to form the resultant string.
An even better approach is to split the string on ; and use #Sergey N Lukin's Comparator to sort the values
String s = "[160,190];[650,790];[901,974];[401,540];[60,90];";
String[] values = s.split(";");
Set<String> sortedValues = new TreeSet<>(new TokensComparator());
sortedValues.addAll(Arrays.asList(values));
Eventually, join the set's elements with a semi-colon(;) using a loop or Google Guava's Joiner
Joiner.on(';').join(sortedValues);
The normal approach is to split the string by the delimiting character (;) and insert the elements into a sorted set (e.g., TreeSet). Then you can simply iterate over the set and join the elements into a string using the delimiter again. Since you need to sort numerically, you have to implement a Comparator and pass an instance to the TreeSet constructor.
The benefit of this approach is that there is no need for an external sort. The collection will maintain the values in sorted order so you simply iterate over the collection to recover the sorted elements.
Simple example:
import java.util.*;
public class Main {
public static void main(String[] args){
String s="[160,190];[650,790];[901,974];[401,540];[60,90]";
String[] stringArray = s.split(";");
Arrays.sort(stringArray,new TokensComparator());
String newString=Main.join(stringArray,";");
System.out.print(newString);
}
static String join(String[] stringArray, String delimiter) {
StringBuilder builder = new StringBuilder();
for (int i=0; i<stringArray.length; i++) {
builder.append(stringArray[i]);
builder.append(delimiter);
}
return builder.toString();
}
static class TokensComparator implements Comparator<String> {
public int compare(String s1, String s2) {
String token1 = s1.substring(1,s1.length()-1).split(",")[0];
String token2 = s2.substring(1,s2.length()-1).split(",")[0];
return Integer.compare(Integer.parseInt(token1),Integer.parseInt(token2));
}
}
}

formating return string for map as a string but get errors

i have this
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Scanner;
import static java.lang.System.*;
public class Relatives
{
private Map<String,Set<String>> map;
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
public void setPersonRelative(String line)
{
String[] personRelative = line.split(" ");
String person = personRelative[0];
String relative = personRelative[1];
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new TreeSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
}
/**
* Returns the String version of the set containing person's relatives
* (see last line of sample output)
* #param person the person whose relative set should be returned as a String
* #param the string version of person's relative set
*/
public String getRelatives(String person)
{
return map.keySet();
}
how can i return a map as a string and make it look like this
Bob is related to John Tom
Dot is related to Chuck Fred Jason Tom
Elton is related to Linh
i have tried typecasting although i didnt think it would work and parse which also didnt work and taht is what i have currently
I'd start with something like this:
public String getRelatives(String person)
{
StringBuilder sb = new StringBuilder();
sb.append(person);
sb.append(" is related to ");
for(String relative : map.get(person))
{
sb.append(relative);
sb.append(' ');
}
return sb.toString();
}
Or if you want to get a little more complicated, and handle the case where someone isn't related to anyone nicely:
public String getRelatives(String person)
{
StringBuilder sb = new StringBuilder();
sb.append(person);
Set<String> relatives = map.get(person);
if(relatives == null || relatives.isEmpty())
{
sb.append("is not related to anyone.");
}
else
{
sb.append(" is related to ");
for(String relative : relatives)
{
sb.append(relative);
sb.append(' ');
}
}
return sb.toString();
}
Provided you initialized the map correctly, and the sets that the map maps to, you should be fine.
Basically you create a StringBuilder (which may be overkill for this, but it's still good practice), stuff it with the things you want, then call its .toString() method.
The for loop just iterates over the contents of the Set, and stuffs the relative's name in the StringBuilder, along with a space character to space things out.
Other notes:
private Map<String,Set<String>> map;
public Relatives()
{
map = new TreeMap<String,Set<String>>();
}
Can just be:
private Map<String, Set<String>> map = new TreeMap<String, Set<String>>();
or, if using Java 7, simply:
private Map<String, Set<String>> map = new TreeMap<>();
(Note that this way, there's no need for an explicit constructor if it was just for initializing the map)
I'd also change this:
if(map.containsKey(person))
{
map.get(person).add(relative);
}
else
{
Set<String> relatives = new TreeSet<String>();
relatives.add(relative);
map.put(person,relatives);
}
To:
if(!map.containsKey(person))
{
map.put(person, new TreeSet<String>());
}
map.get(person).add(relative);
Simpler, and avoids redundancy

Is there a utility method to separate a list by given string?

Is there something like the following in Apache Common Lang or Spring Utils or do you write your own Util method for this?
List<String> list = new ArrayList<String>();
list.add("moo");
list.add("foo");
list.add("bar");
String enumeratedList = Util.enumerate(list, ", ");
assert enumeratedList == "moo, foo, bar";
I remember the use of implode in php, this is what i search for java.
$array = array('lastname', 'email', 'phone');
$comma_separated = implode(",", $array);
You can use StringUtils.join(Object[] array, String delimiter) (from commons-lang) in the following way:
String enumeratedList = StringUtils.join(list.toArray(), ", ");
Google Collections provides the Joiner class, which can be used like this:
public class Main {
public static void main(String[] args) {
List<String> list = Lists.newLinkedList();
list.add("1");
list.add("2");
list.add("3");
System.out.println(Joiner.on(", ").join(list));
}
}
It's pretty trivial to inplement if you don't want a dependency on commons-lang. It's also not great to convert a List to an Array simply to join it again into a String. Instead just iterate over your collection. Even better than using Collection is using Iterable which handles anything which can be iterator over (even some sort of stream or Collection of unknown length).
import java.util.Arrays;
import java.util.Iterator;
public class JoinDemo {
public static String join(String sep, Iterable<String> i) {
StringBuilder sb = new StringBuilder();
for (Iterator<String> it = i.iterator(); it.hasNext();) {
sb.append(it.next());
if (it.hasNext())
sb.append(sep);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(join(",", Arrays.asList(args)));
}
}
Example:
# javac JoinDemo.java
# java JoinDemo a b c
a,b,c

Categories

Resources