2

Main idea of this program is to generate a tweet randomly (140 characters) of certain chars a-z + '.' + ',' + ';' + ':'among others...

Problem is, when i generate and add each char to the list everything looks fine (I added a line to check which char gets added). BUT whenever I print the result most of the time I get null+140other chars. Here's the code:

import java.util.Scanner;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Random;

public class P1{

String tweet;
List<Character> caracteres;
Random rand;
char nextChar;
int number;

public P1(){
    caracteres = new ArrayList<Character>();
    rand= new Random();

    for(int i=97; i<=122; i++){
        nextChar = new Character((char)i);
        caracteres.add(nextChar);
    }
    caracteres.add(new Character((char)58));
    //System.out.println("Added" + new Character((char)58));
    caracteres.add(new Character((char)59));
    //System.out.println("Added" + new Character((char)59));
    caracteres.add(new Character((char)32));
    //System.out.println("Added" + new Character((char)32));
    caracteres.add(new Character((char)13));
    //System.out.println("Added" + new Character((char)13));
    caracteres.add(new Character((char)63));
    //System.out.println("Added" + new Character((char)63));
    caracteres.add(new Character((char)33));
    //System.out.println("Added" + new Character((char)33));
    caracteres.add(new Character((char)46));
    //System.out.println("Added" + new Character((char)46));
    caracteres.add(new Character((char)44));
    //System.out.println("Added" + new Character((char)44));
}

public String generaTweet(){
    for(int i=0; i<140; i++){
        number = Math.abs((rand.nextInt())%34);
        if(number == 13){
            tweet+= '\n';
        }
        else{
            tweet+= caracteres.get(number);
        }
        System.out.println(i + ". " + caracteres.get(number)); //added char
    }
    return tweet;
}


public static void main(String [] args){
    P1 ejer = new P1();
    System.out.println(ejer.generaTweet());
}

}
Alan
  • 361
  • 3
  • 22
  • @TAsk he wrote it in his question - he's generating a random tweet. – Nir Alfasi Sep 15 '15 at 02:22
  • Because that's the main idea, array list just has the full list of valid chars. So when i access with a random number what i'm doing is adding a random char to the String tweet. – Alan Sep 15 '15 at 02:24

3 Answers3

3

It's because you never initialize the field tweet. Your constructor should look something like this:

public P1(){
    tweet = "";
    //....
}
Michael
  • 2,673
  • 1
  • 16
  • 27
  • This made the trick, didn't realize, thanks. As soon as I can I'll mark it as correct since you were also the first. – Alan Sep 15 '15 at 02:30
  • 1
    @Alan - Though your problem is solved but consider to use StringBuilder.apped() to keep adding content in your string instead of `+` the concatenation operator on String – Raman Shrivastava Sep 15 '15 at 02:32
  • Have to ask what's the problem with just concatenation? Thanks in advance. – Alan Sep 15 '15 at 02:35
  • 2
    @Alan each time you call code like `result = result+otherString` in a loop (assuming that `result` is String) you are creating temporary StringBuilder which will need to first copy characters from `result`, then characters from `otherString` and then create new string object (which will be sum of copied characters). So in each iteration you need to spend more time to copy previous `result` since it will get larger. Instead it is better to explicitly create your own `StringBuilder` and append to it all parts, then convert it `toString()`. – Pshemo Sep 15 '15 at 02:39
  • 1
    @Alan check out this link: http://stackoverflow.com/questions/14927630/java-string-concat-vs-stringbuilder-optimised-so-what-should-i-do – Michael Sep 15 '15 at 02:41
2

String tweet; is a field, and since it was not explicitly initialized it will hold its default value which for objects like Strings is null. Now when you call

tweet += someString

you end up with

tweet = tweet + someString;

and since at start tweet is null you are getting

null + someString

To solve this problem you could initialize tweet with blanks string

String tweet  = "";

Other improvements:

You should avoid concatenating strings in loop. Better solution would be using StringBuilder instead and append new chunks of text to it.

Also avoid magic numbers. Instead of cryptic

for(int i=97; i<=122; i++){
    nextChar = new Character((char)i);
    caracteres.add(nextChar);
}

you could write

for (char ch = 'a'; ch<='z'; ch++) {
    caracteres.add(ch);
}

which is clearer (you also don't need to explicitly create instances of Character class since Java will box char to Character for you automatically).

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • @Alan No problem, accepting answer is personal choice and as long as you accepted answer is correct I don't mind you picking other answer :) I am glad you learned something also from this answer. – Pshemo Sep 15 '15 at 02:36
0

The line

String tweet;

should be

String tweet = "";

tweet starts of as null so the first time you add a character the concatenation operator + uses the String "null" for tweet.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116