replace null or empty data in string builder with some message - java

I have a string builder and it contains some data.I want to ensure whenever there is a null or empty("") data in it, i want to replace it with some message e.g not available. This is a huge data and i cannot go and replace each and every String.
Following is a snippet of code :
Stringbuilder sb = new Stringbuilder();
String a = "10";
String b = 13;
sb.append("entity.id=").append(a).append("entity.value=").append(b);
sb.toString;
So whenever entity.id or entity."ANYTHING" equals "null" or is empty, it should be replaced with a message like entity.id= not available

Without knowing your exact requirements, this may not be perfect, but is one option:
public void myCustomAppend(Appendable a, CharSequence cs){
if(cs == null || cs.length() == 0){
a.append("(not available)");
}else{
a.append(cs);
}
}
myCustomAppend(sb, "entity.id=");
myCustomAppend(sb, a);
myCustomAppend(sb, "entity.value=");
myCustomAppend(sb, b);
Some improvements to this could include creating it as a custom object with it's own state - preventing the need to keep passing-in the same reference to the StringBuilder, as well as allowing for successive calls to be chained (as you had them in the original question).

Create a function, for example...
public String checkString(String str) {
if(str == null || str.isEmpty())
return "N/A";
return str;
}
Call it on a String you want to append.
sb.append("entity.id=").append(checkString(a)).append("entity.value=").append(checkString(b));

Consider using Guava's Joiner class.
List<String> values = newArrayList("value1", "value2", a, b, c);
String result = Joinger.on(" ").useForNull("null").join(values);
You can also use "omitNull" instead of "useForNull"
Seeing what you are doing, you might also want to look at MoreObjects.ToStringHelper
Guava docs

check the strings if they are empty, before you append it. If the string is empty you can append a your message instead of the content of the data strings. ;)

Related

List to String using toString() in java

I'm having ArrayList Contains of String. I would like to check whether the character is present in the arraylist. I'm using the following code.
if(list.toString.contains(char))
{
// enter code here
}
Can i use this toString() method. What is the drawback?
It would be a really bad idea to use List.toString() and search that. Your code should probably look something like this :
Iterator it = list.getIterator();
char searchChar = 'S';
while (it.hasNext())
{
String s = (String) it.next();
if ( s.contains(searchChar) )
{
//Found the char!
}
}
No you cannot go ahead with arraylist.toString(), as it will not provide string representation of contents in String.
Better approach is to iterate over list and check, as below.
for(String detail:listString){
if(detail.contains('X')) //replace 'X' with your character
{
// do somethng
}
}
Try this,
Arrays.toString(inputList.toArray()).contains(searchValue);
list.toString() gives you a string representation of a list and thus it contains more characters then just the concatenated list elements
[stringElement1, stringElement2, ... ]
Therefore your approach will not work if the character you are looking for is , , , [ or ].
And keep in mind that this string representation is implementation specific. It might not work for other list implementations than ArrayList
I would recommend to write a method linke this:
private boolean listElementContains(List<String> list, String subString){
for(String element : list){
if(element.contains(subString)){
return true;
}
}
return false;
}
You can call toString() on any Java Object. List is an Object which contains (you guessed it) a list of other Objects. Therefore, you can also call toString() on each Object contained within the List. You should read about inheritance in Java.
In your particular case, you have a List of Strings. What you actually want to do is check each String in the List to see if the String contains a particular character. Topics you may want to read about include iteration, for loops, and for each loops.
If I understand this correctly, your code would look like this:
List<String> strings = new ArrayList<>();
//add strings to list
for (String string : strings) {
//Look for some character c
if (string.indexOf(c) >= 0) {
return true;
}
}
return false;
On the matter of list.toString, that simply returns a representation of the object as a string; it has nothing to do with the contents. Think of it like a label on a box of stuff that says "Junk." The box is labeled Junk, but you have no idea what's in it.
What's nearly certain is that toString will return a nonsense label for the object in memory. So to get at what's inside, you need to loop through the contents as shown above.
if(list.toString.contains(char))
String's contains() method won't take char as param, instead check with indexOf
Your code works, with little modifications.
A small example here:
List<String> list= new ArrayList<>();
list.add("test");
list.add("test2");
if (list.toString().indexOf('t') > -1) // True
{
System.out.println("yes there");
}
Note:
As a workaround, Make an char array and add your char in to that array and then use contains method.

StringBuilder appends null as "null"

How come?
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append((String)null);
sb.append(" World!");
Log.d("Test", sb.toString());
Produces
06-25 18:24:24.354: D/Test(20740): Hellonull World!
I expect that appending a null String will not append at all!!
BTW, the cast to String is necessary because StringBuilder.append() has a lot of overloaded versions.
I simplified my code to make a point here, in my code a got a method returning a string
public String getString() { ... }
...
sb.append(getString());
...
getString() sometimes returns null; now I have to test it if I want to use a StringBuilder!!!!
Furthermore, let's clarify my question here: how can I get StringBuilder.append() to accept, in an elegant way, a null string, and not convert it to the literal string "null".
By elegant I mean I don't want to get the string, test if it is null and only then append it. I am looking for an elegant oneliner.
How come?
Its clearly written in docs
The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are appended.
So please put a null check before append.
That's just the way it is. null is appended as "null". Similarly, when you print null with System.out.println(null) you print "null".
The way to avoid that is that method that returns string getString() checks for null:
public String getString() {
...
if (result == null) {
return "";
}
}
It behaves like this, because null isn't an empty String as you think of it. Empty Stringwould be new String("");. Basically append() method appends "null" if it gets null value as a parameter.
EDIT
My previous answer was not reflecting the appropriate reason for such behaviour of StringBuilder as asked by OP. Thanks to #Stephen C for pointing out that
I expect that appending a null String will not append at all!!
But it is appending. The reason for such behaviour of StringBuilder is hidden in implementation detail of append(Object obj) method which takes us to AbstractStringBuilder#append(String str) method which is defined as follows:
public AbstractStringBuilder append(String str) {
if (str == null) str = "null"; -->(1)
//.......
return this;
}
It clearly specifying that if the input String is null then it is changed to String literal "null" and then it processes further.
How can I get StringBuilder.append() to accept, in an elegant way, a null string, and not convert it to the literal string "null".
You need to check the given String for null explicitly and then proceed. For example:
String s = getString();
StringBuffer buf = new StringBuffer();
//Suppose you want "Hello "<value of s>" world"
buf.append("Hello ");
buf.append(s==null?" world" : s+" world");
AbstractStringBuilder class appends an object through String.valueOf(obj) method which in turn converts NULL into string literal "null". Therefor there is no inbuilt method to help you here. You have to either use ternary operator within append method or write a utility method to handle it, as others suggested.
This will work for you
public static String getString(StringBuilder sb, String str) {
return sb.append(str == null ? "" : str).toString();
}
What about writing an utility method like
public static void appendString(StringBuilder sb, String st) {
sb.append(st == null ? "" : st);
}
or this the ternary operator is very handy.
String nullString = null;
StringBuilder sb = new StringBuilder();
sb.append("Hello");
if (nullString != null) sb.append(nullString);
sb.append(" World!");
Log.d("Test", sb.toString());
There! I did it in one line :)
One line?
sb.append((getString()!=null)?getString():"");
done. But is pointless as have to call getString() twice
As was suggested build check into getString() method
You can also write decorator for StringBuilder, which can check whatever you want:
class NotNullStringBuilderDecorator {
private StringBuilder builder;
public NotNullStringBuilderDecorator() {
this.builder = new StringBuilder();
}
public NotNullStringBuilderDecorator append(CharSequence charSequence) {
if (charSequence != null) {
builder.append(charSequence);
}
return this;
}
public NotNullStringBuilderDecorator append(char c) {
builder.append(c);
return this;
}
//Other methods if you want
#Override
public String toString() {
return builder.toString();
}
}
Example of usage:
NotNullStringBuilderDecorator sb = new NotNullStringBuilderDecorator();
sb.append("Hello");
sb.append((String) null);
sb.append(" World!");
System.out.println(sb.toString());
With this solution you have not to change POJO classes.

Null pointer exception while checking if a string is present in a string array in android?

I have an application which requires to check if a String is present in an array of String type, before adding it so as to avoid duplication. To do this, I wrote the following function:
public boolean arrayHas(String[] arr, String str)
{
for(int i=0;i<arr.length;i++)
{
if(arr[i].equals(str))
return true;
}
return false;
}
To invoke this function, I'm using:
if(!arrayHas(contacts,str))
{
contacts[i] = str;
i++;
}
contacts and str are declared as follows
public static String contacts[] = new String[]{};
String str = "";
Bundle bun = getIntent().getExtras();
str = bun.getString("key");
Elements are added to 'contacts' only through the main code, it is empty at the beginning. I tried adding a toast to display the value of 'str' received through the intent and it works fine. But I'm getting a NullPointerException in the 'if' statement in the arrayHas function. Could someone help me out?
Seems that you haven't initialized the array with elements. So all of them are NULL.
In you arrayHas function check if the element you are comparing with is a null or not.
if(arr[i] != null && arr[i].equals(str) )
{
// do your operation
}
Also before calling arrayHas function in
if(arrayHas(contacts,str)) { }
put a check if contacts is null or not.
Two issues:
First: add a null check in if as:
if(arr[i] != null && arr[i].equals(str))
because that position may not have assigned with a valid string yet e.g. in the very beginning, no assignment is made and arr[0] is null so comparison will result into NullPointerException.
Second: I think you want to check the not ie. ! condition in this check:
if(!arrayHas(contacts,str))
{
contacts[i] = str;
i++;
}
If you want to avoid duplication, use a java.util.Set<String>, it will take care of it for you. You can always uso toArray() if you really need an array later on.
If you care about the order of your elements, you can also use a java.util.List, and check the presence of the element with list.contains(str)
Use this instead :
String contacts[] = new String[10];
String str = "somethiung";
if(Arrays.asList(contacts).contains(str))
{
contacts[i] = str;
i++;
}
Arrays.asList(.).contains(.) gives you a much better way to test if a string is present in an array.
By the way make sure that contacts and str are properly initialized.
Just a suggestion to code style. Try to defensive programming., ie. you are checking whether the string str is present in arr in that case always do the check in reverse ie., str.equals(arr[i]), so that unnecessary NPEs wont be raised.
In this case an NPE could be raised at 2 points, if arr is null .length and .equals will throw NPE's. From this its evident that, either arr is null , or arr[i] is null.
Find the method where arr is filled with data, there something is going wrong.
thanks
You must not have initialized your contacts[] but it might be the case like str[0]=null but str[1]="something";
in that case change
arr[i].equals(str) to `str.equals(arr[i])` as str is less likely to be null
- I think you are trying to find whether a String is a present in the Array of Not.
- First use Collections cause that will be much more flexible in comparision to Array.
- Use Collections.contains() method to find the String if present of not.
For example if you are using List:
List<String> list = new ArrayList<String>();
list.contains("string_to_be_found");

Java contains doesn't work as expected because "someString" != "someString"

I want check whether a String value val is contained within a List of Strings lets call it stringList.
I am doing this
if(stringList.contains(val)){
System.out.println("The value is in there");
}
else{
System.out.println("There's no such value here");
}
But it always seems to be that the value is not included. Is this because two String values that have the same characters are not actually equal? For a "home-made" class I could implement hashCode() and equals() and fix this, what can I do for String data?
EDIT:
The way I am getting val is outlined here:
List<String> stringList = new ArrayList<String>();
stringList.add("PDT");
stringList.add("LDT");
stringList.add("ELNE");
String myFile = "/folder/myFile";
InputStream input = new FileInputStream(myFile);
CSVReader reader = new CSVReader(new InputStreamReader(input), ',','"', 1);
String[] nextLine;
try {
while ((nextLine = reader.readNext()) != null) {
if (nextLine != null) {
if (nextLine[6] != null){
String val = nextLine[6];
if(stringList.contains(val)){
System.out.println("Success");
}
}
}
}
ArrayList.contains() uses Object.equals() to check for equality (hashCode() is not involved in List). This works well for strings. Probably, your string really isn't contained in the list...
You've probably overlooked some whitespace or upper/lower-case or encoding difference...
More code please!
This works:
import java.util.*;
public class Contains {
public static void main(String[] args) {
List<String> stringList = new ArrayList<String>();
stringList.add("someString");
String val = new String("someString");
if (stringList.contains(val)) {
System.out.println("The value is in there");
} else {
System.out.println("There's no such value here");
}
}
}
That doesn’t sound right: contains uses equals rather than ==, so if the string is in the list, it should be found. This can be verified in the indexOf method of the superclass AbstractList used by ArrayList.
Following your edit, make sure you trim strings before doing contains, as otherwise they may contain the newline character(s).
Try the following, first make the check more concrete by iterating the list and checking each element separately. Than, when you hit the elements that you are expecting to be equal, This is what you are supposed to be looking at. Check to see if they are really equal. Maybe there is a case difference? (or some other elusive but plain difference like white space?)
Try to override equals(){}, so that you can specify which property needs to compare equality .... :P

The best way to test if a returned string is null in Java

I have a function that concatenate a set of strings like this:
StringBuffer sb = new StringBuffer();
sb.append(fct1());
sb.append(fct2());
sb.append(fct3());
Where fct1(), fct2() and fct3() should return a String.
The problem is that I must test the returned values like this :
sb.append(fct1() == null ? "" : fct1());
because I get an exception if the value is null.
The problem is that I have many instructions like this and, above all, I can't modify these functions that return the strings(fct1, fct2 and fct3).
Is there a solution that will "sanitize" automatically my strings?
Thank you.
PS: I created a function that can do it:
public String testNullity(String aString){
aString == null ? "" : aString;
}
so that I can call it like this:
sb.append(testNullity(fct1));
sb.append(testNullity(fct2));
...
Another alternative might be
public class SafeStringBuilder {
private StringBuilder builder = new StringBuilder();
public SafeStringBuilder append(String s) {
if (s != null)
builder.append(s);
return this;
}
}
If you don't mind introducing a dependency, use Guava's Joiner instead of StringBuffer:
Joiner j = Joiner.on("").skipNulls();
StringBuilder sb = new StringBuilder();
j.appendTo(sb, fct1());
j.appendTo(sb, fct2());
j.appendTo(sb, fct3());
String result = sb.toString();
// or even just
Joiner j = Joiner.on("").skipNulls();
String result = j.join(fct1(), fct2(), fct3());
N.B. In general, unless you need StringBuffer's thread safety, you should use StringBuilder instead. Same API, better performance.
There is nothing whatsoever you can do to make this solution simpler except shortening the method name. (There might be a solution using aspect-oriented programming, but on the whole I don't really consider that simpler.)
Unfortunately your solution with testNullity() is the best you can get with Java (consider better naming though). In fact, there is already a method that does that: StringUtils.html#defaultString.
You can create your own wrapper around StringBuffer:
class MyStringBuffer {
StringBuffer _sb = new StringBuffer();
public boolean append(String s) {
_sb.append(s==null ? "" : s);
return s == null;
}
public String toString() { return _sb.toString(); }
}
There is no such function in the standard API, though some methods (which do other things) have it built in.
For example, System.getProperty() has a variant which takes a default value, and if it can't find the given property, it will not return null, but the given default value. You might think of providing your fct* methods with such a "default" argument, if it makes sence.
I think C# has a ?? operator which does about what you want (you would call sb.append(fct2() ?? "")), but I suppose Java will not add any new operators soon.
A better variant of your checking function would be this:
public void appendIfNotNull(StringBuffer sb, String s) {
if(s != null) {
sb.append(s);
}
}
This avoids the superfluous append call with an empty string if there is nothing to append.

Categories