Reputation: 422
I am currently struggling with a code. The problem mainly occurs with the array and trying to reach back.
This file only requires a main method that does the following until the user enters "quit":
• Prompts the user for a URL to visit, to go back (only when possible), or to quit
• Visits and displays an entered URL
• Goes back to and displays the previously visited URL (if possible)
• If the user enters "back" when there isn't a page to go back to, an appropriate message should be displayed.
Here's an example of an output:
Enter a URL or "quit": back
No URL to go back to
Enter a URL or "quit": http://www.wwe.com
Current URL: http://www.wwe.com
Enter a URL or "quit": back
No URL to go back to
Current URL: http://www.wwe.com
Enter a URL or "quit": http://www.amazon.com
Current URL: http://www.amazon.com
Enter a URL, "back", or "quit": http://www.google.com
Current URL: http://www.google.com
Enter a URL, "back", or "quit": back
Current URL: http://www.amazon.com
Enter a URL, "back", or "quit": back
Current URL: http://www.wwe.com
Enter a URL or "quit": quit
Here's my current code:
public class BrowsingHistory
{
public static void main(String [] args)
{
Scanner url = new Scanner(System.in);
String web = "";
String currentURL = "";
Stack<String> myStack = new Stack<>();
System.out.print("Enter a URL or \"quit\": ");
web = url.nextLine();
while (!web.contains("quit"))
{
System.out.println();
System.out.print("Enter a URL, \"back\", or \"quit\": ");
web = url.nextLine();
if(web.equals("back") && myStack.isEmpty())
{
System.out.println("No URL to go back to");
}
else if(!web.equals("back"))
{
myStack.push(web);
System.out.println("Current URL: " + myStack.peek());
}
else
{
System.out.println("No URL to go back to");
System.out.println("Current URL: " + myStack.pop());
}
}
}
}
Here are the tests it needs to pass, just so it's clarified:
@Test
void testMain()
{
setInput("back\nhttp://www.uwec.edu\nback\nhttp://www.amazon.com\nhttp://. w.google.com\nback\nback\nquit\n");
BrowsingHistory.main(null);
String mainOutput = outContent.toString();
Scanner driverOut = new Scanner(mainOutput);
String outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (initial prompt problem)");
Error happens in this line below:
assertEquals("No URL to go back to", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (can't go back issue)");
the rest of this passes:
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("Current URL: http://www.uwec.edu", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("No URL to go back to", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (can't go back issue)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Current URL: http://www.uwec.edu", outputLine.trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("Current URL: http://www.amazon.com", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL, \"back\", or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("Current URL: http://www.google.com", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL, \"back\", or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("Current URL: http://www.amazon.com", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL, \"back\", or \"quit\":", outputLine.substring(0, outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertEquals("Current URL: http://www.uwec.edu", outputLine.substring(outputLine.indexOf(":")+1).trim(), "BrowsingHistory doesn't run as expected (current url problem)");
outputLine = getNextOutputLine(driverOut);
assertEquals("Enter a URL or \"quit\":", outputLine.trim(), "BrowsingHistory doesn't run as expected (prompt problem)");
assertFalse(driverOut.hasNext(), "BrowsingHistory doesn't run as expected (quit problem)");
driverOut.close();
}
Upvotes: 0
Views: 171
Reputation: 23665
Using Stack class instead of an ArrayList would make your life much easier.
Use push() to add new urls to stack.
Use empty() to check if you can go back.
Use pop() to go back.
EDIT - supporting forward
If you want to support a 'forward' comand as well, you can use a second stack and push the urls you popped from the history stack on that forward-stack. When the 'forward' command is entered, check, if the forward-stack is empty, and if not, pop the url from there and push it back onto the history-stack.
EDIT 2 - example code
Here is some rudimentry code to explain the 2 stacks solution:
Stack<String> historyStack = new Stack<>();
Stack<String> forwardStack = new Stack<>();
String currentUrl = null;
boolean running = true;
while(running) {
String input = getUserInput();
switch(input) {
case "quit":
running = false;
break;
case "back":
if (!historyStack.empty()) {
if (currentUrl != null) {
forwardUrl.push(currentUrl);
}
currentUrl = historyStack.pop();
System.out.println(currentUrl);
} else {
System.out.println("nothing to go back to");
}
break;
case "forward":
if (!forwardStack.empty()) {
if (currentUrl != null) {
historyStack.push(currentUrl);
}
currentUrl = forwardStack.pop();
System.out.println(url);
} else {
System.out.println("nothing to go forward to");
}
break;
default:
if (currentUrl != null) {
historyStack.push(currentUrl);
}
currentUrl = input;
System.out.println(url);
// entering a new url makes forward stack invalid
forwardStack.clear();
}
}
Upvotes: 2
Reputation: 15433
You can change your logic to as follows :
ArrayList<String> webs = new ArrayList<String>();
String web = "";
Scanner url = new Scanner(System.in);
int count = 0;
while (!web.contains("quit")) {
System.out.println("Enter a URL or \"quit\":");
web = url.next();
if (!web.equals("back")) {
webs.add(web);
count = webs.size();
} else if (web.equals("back") && !webs.isEmpty()) {
if (count > 0) {
count--;
System.out.println(webs.get(count));
} else {
System.out.println("No url to go back to");
}
}
}
Note the following points :
As others have pointed out, the same can be achieved much more easily by using a Stack
Scanner url = new Scanner(System.in);
String web = "";
Stack<String> myStack = new Stack<>();
while (!web.contains("quit")) {
System.out.println("Enter a URL or \"quit\":");
web = url.next();
if (!web.equals("back") && !web.equals("quit")) {
myStack.push(web);
} else {
if (!myStack.isEmpty()) {
System.out.println(myStack.pop());
} else {
System.out.println("No url to go back to");
}
}
}
Upvotes: 1
Reputation: 18255
You use incorrect data structure. List
is OK, but using Stack
is more correct here: you add to the end and retrieve from the end, this id LIFO.
private static final String QUIT = "quit";
private static final String BACK = "back";
try (Scanner url = new Scanner(System.in)) {
Deque<String> stack = new LinkedList<>();
while (true) {
System.out.print("Enter a URL, \"" + BACK + "\" or \"" + QUIT + "\": ");
String str = url.next();
if (str.equalsIgnoreCase(QUIT))
break;
else if (str.equalsIgnoreCase(BACK)) {
if (!stack.isEmpty())
stack.pop();
System.out.println(stack.isEmpty() ? "No URL to go back to" : stack.element());
} else
stack.push(str);
}
}
Demo
Enter a URL, "back" or "QUIT": http://www.wwe.com
Enter a URL, "back" or "QUIT": http://www.amazon.com
Enter a URL, "back" or "QUIT": http://www.google.com
Enter a URL, "back" or "QUIT": back
http://www.amazon.com
Enter a URL, "back" or "QUIT": back
http://www.wwe.com
Enter a URL, "back" or "QUIT": back
No URL to go back to
Enter a URL, "back" or "QUIT": quit
Upvotes: 0