Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialnaga bonar
3,338 PointsPlease help, I got error like this "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space"
My code runs normally in local (IntelliJ IDE) but when i posted it into the exercise, i got error like this "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space".
I search that error in google, it refer to memory leak. I have no idea how to find the root cause. Anybody knows where the root cause is? Thanks before hand.
Below are my codes: Main.java
package com.teamtreehouse;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
// write your code here
// TODO:csd - Instantiate a new Prompter object and prompt for the story template
Prompter prompter = new Prompter();
String story = "Thanks __name__ for helping me out. You are really a __adjective__ __noun__ and I owe you a __noun__.";
Template tmpl = new Template(story);
// TODO:csd - Use the prompter object to have it do the prompting, censoring and outputting. Call Prompter.run
prompter.run(tmpl);
/*List<String> fakeResults = Arrays.asList(
"friend",
"talented",
"java programmer",
"high five");*/
// TODO:csd - This should really happen in the Prompter.run method, let's get these implemetation details out of the main method
/*String results = tmpl.render(fakeResults);
System.out.printf("Your TreeStory:%n%n%s", results);*/
}
}
Prompter.java
package com.teamtreehouse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Prompter {
private BufferedReader mReader;
private Set<String> mCensoredWords;
public Prompter() {
mReader = new BufferedReader(new InputStreamReader(System.in));
loadCensoredWords();
}
private void loadCensoredWords() {
mCensoredWords = new HashSet<String>();
Path file = Paths.get("resources", "censored_words.txt");
List<String> words = null;
try {
words = Files.readAllLines(file);
} catch (IOException e) {
System.out.println("Couldn't load censored words");
e.printStackTrace();
}
mCensoredWords.addAll(words);
}
public void run(Template tmpl) {
List<String> results = null;
try {
results = promptForWords(tmpl);
} catch (IOException e) {
System.out.println("There was a problem prompting for words");
e.printStackTrace();
System.exit(0);
}
// TODO:csd - Print out the results that were gathered here by rendering the template
System.out.println(tmpl.render(results));
}
/**
* Prompts user for each of the blanks
*
* @param tmpl The compiled template
* @return
* @throws IOException
*/
public List<String> promptForWords(Template tmpl) throws IOException {
List<String> words = new ArrayList<String>();
for (String phrase : tmpl.getPlaceHolders()) {
String word = promptForWord(phrase);
words.add(word);
}
return words;
}
/**
* Prompts the user for the answer to the fill in the blank. Value is guaranteed to be not in the censored words list.
*
* @param phrase The word that the user should be prompted. eg: adjective, proper noun, name
* @return What the user responded
*/
public String promptForWord(String phrase) throws IOException {
// TODO:csd - Prompt the user for the response to the phrase, make sure the word is censored, loop until you get a good response.
String userInput;
System.out.printf("Please input a %s: %n", phrase);
userInput = mReader.readLine();
while(userInput == null || (mCensoredWords.contains(userInput))){
System.out.printf("Please input a NICE %s: %n", phrase);
userInput = mReader.readLine();
}
return userInput.trim();
}
}
Template.java
package com.teamtreehouse;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Template {
/**
* The string format that is waiting to receive values
*/
private String mCompiled;
private List<String> mPlaceholders;
/**
* @param text A template with double underscored surrounded placeholders. eg: Hello __name__!
*/
public Template(String text) {
// Match on double underscore surrounded words, like __name__ or __proper noun__
Pattern pattern = Pattern.compile("__([^__]+)__");
Matcher matcher = pattern.matcher(text);
mPlaceholders = new ArrayList<String>();
while (matcher.find()) {
String label = matcher.group(1);
mPlaceholders.add(label);
}
mCompiled = matcher.replaceAll("%s");
}
/**
* @return Ordered names of placeholders in the template
*/
public List<String> getPlaceHolders() {
return mPlaceholders;
}
/**
* Given a list of values, replaces the fill in the blanks in order.
*
* @param values The replacements for the fill in the blank
* @return The filled out TreeStory
*/
public String render(List<String> values) {
// String.format accepts the templates and Object... (a variable amount of objects)
return String.format(mCompiled, values.toArray());
}
}
2 Answers
Alexander Nikiforov
Java Web Development Techdegree Graduate 22,175 PointsHi,
I believe that the error exists, but in order to pass the challenge you have to do all Craigs TODOs properly.
Below I provide you how your Main class should look like, so that you can fill out the missing methods in Prompter your self.
I. You've done // TODO:csd - Print out the results that were gathered here by rendering the template
correct, great job!
II. // TODO:csd - Prompt the user for the response to the phrase, make sure the word is censored, loop until you get a good response.
is done incorrectly. Why?
Because you return trimmed input: return userInput.trim();
You cannot return trimmed input, because you change your user input, if user types "Alex", your program will return "alex", which is not correct.
III. I will give you sudo code with how your Main class should look like:
public class Main {
public static void main(String[] args) {
// write your code here
// TODO:csd - Instantiate a new Prompter object and prompt for the story template
Prompter prompter = new Prompter(); // great job ! this is correct
// This one is wrong, because TODO clearly says, "prompt for story template",
// which means implement Prompter.promptForStory() method that returns Story
// String story = "Thanks __name__ for helping me out. You are really a __adjective__ __noun__ and I owe you a __noun__."; //
// So it should be like this:
String story = prompter.promptForStory();
// implement the method in Prompter. All it does - it prompts user for story, very simple, very easy.
// I'm sure you can do it. You've got this
Template tmpl = new Template(story); // correct : will work
// TODO:csd - Use the prompter object to have it do the prompting, censoring and outputting. Call Prompter.run
prompter.run(tmpl); // correct : will work
// this TODO you've done correctly in Prompter.run() method! Great job! :)
// TODO:csd - This should really happen in the Prompter.run method, let's get these implemetation details out of the main method
/*String results = tmpl.render(fakeResults);
System.out.printf("Your TreeStory:%n%n%s", results);*/
}
}
Post back the refactored code, so that I can take a look. Good Luck! You've got this :)
Doli Harahap
6,246 PointsI have same problem. It can be run correctly in Intellij, but got OOM in the challenge.
naga bonar
3,338 Pointsnaga bonar
3,338 PointsHi Alexander Nikiforov,
I tried like what you've advised. i change my code into like below: Main.java
Prompter.java
and the template.java still the same. But i still got error like below:
Please help me find out again. thanks a lot for your support.
Alexander Nikiforov
Java Web Development Techdegree Graduate 22,175 PointsAlexander Nikiforov
Java Web Development Techdegree Graduate 22,175 PointsYeah well. Code looks good except for that method
promptForStory
. I guess I'll just write how it should look like. You've spent enough with that problem.In your method all you do is to define String and print it on your own.
However what you have to do is to actually prompt user for input
Here is code:
Should work. I pasted your code, changed only this method of yours and it worked.
Let me know if it worked for you, and if you understand what is going on in this
promptForStory
methodJose Aguirre
8,145 PointsJose Aguirre
8,145 PointsI just ran into the same problem. Thank you Alexander.