-1

This method returns true if the number passed in contains a 1.

public boolean hasOne(int n) {
  return (n + "").contains("1");
}

What is the purpose of the + "" part? How does that make n a string? (.contains only works with Strings as far as I understand).

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170

3 Answers3

5

An int is a primitive. Adding a primitive to a string will perform an implicit conversion of that primitive to a String and add the two strings together. In this case, the int is converted and "" ( empty String ) is added,

That can be rewritten as:

return Integer.toString(n).contains("1");

or

return String.valueOf(n).contains("1");

or

return String.format("%d", n).contains("1");
nanofarad
  • 40,330
  • 4
  • 86
  • 117
2

Technically speaking, the + operator in Java implies the use of a StringBuilder object when one of the operands is a string. The Java compiler (not the JVM) translates this syntactic sugar to bytecode instructions that invoke methods of the StringBuilder object to perform the concatenation.

The exact equivalent of the piece of code in the question is:

 public boolean hasOne(int n) {
     StringBuilder sb = new StringBuilder();

     sb.append(n); // Which does Integer.getChars(i, spaceNeeded, value);
     sb.append("");

     return sb.toString().contains("1");
 }

As mentioned in other answers to this question, the n + "" construct is by no means an efficient way to convert a primitive integer value to a string - using Integer#toString(int) is definitely the recommended way to do this.

EDIT:

While for the official Oracle JVM "" + n is definitely slower, as it always has been, I have encountered some confusing results while benchmarking on my OpenJDK JVM. While I still stand by my statement that "" + n is sort of an anti-pattern for both performance and clarity reasons, the performance discrepancy I see on OpenJDK is quite interesting.

Community
  • 1
  • 1
thkala
  • 84,049
  • 23
  • 157
  • 201
  • 1
    @user2864740: `"" + n`, however, will create at least two additional objects in the background, rather than just generate the string directly. Just because it's shorter to type doen't make it correct... – thkala May 19 '14 at 22:54
  • 2
    @user2864740: "a particular Java compiler"? Even the Oracle Java 8 compiler works like that when the integer operand is a variable. I would argue that, regardless if we like it or not, that would be the definitive compiler for Java ATM... – thkala May 19 '14 at 23:10
  • @thkala - actually it will create 3 temporary objects, which is even worse! –  May 20 '14 at 01:07
  • 1
    @JarrodRoberson: actually, if you look at the implementation it may not be that bad. `Integer.toString()` creates a single temporary character array. `"" + n` creates a `StringBuilder`, which contains a temporary character array. The difference lies in the `StringBuilder` object itself and the fact that the character array is generally not created with the correct size and that it may not be allocated on the stack... – thkala May 20 '14 at 07:16
  • 1
    That said, I am seeing some weird results with JMH - probably due to the short runtime that does not allow for the extra garbage to become an issue... – thkala May 20 '14 at 07:18
-1

The "contains" method (see javadoc at http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#contains(java.lang.CharSequence) accepts a "CharSequent" as a parameter. The "n + """ creates a "String" object, which is a subclass of "CharSequence".

jordan
  • 959
  • 7
  • 17