Can anyone help with this hasNextLine() error?
Having problems compiling this class. I'm working through a book on java and this is one of the exercises, and they provide most of the code. So this is basically a stock class provided by the book.
Now, the problem I'm having is when compiling i'm getting this error:
cannot find symbol
symbol : method hasNextLine()
location: class StdIn
In relation to this:
// read a graph from an input stream
public Graph(In in, String delimiter) {
st = new ST<String, SET<String>>();
while (in.hasNextLine()) {
String line = in.readLine();
String[] names = line.split(delimiter);
for (int i = 1; i < names.length; i++) {
addEdge(names[0], names[i]);
}
}
}
Now I thought hasNextLine() was part of the Scanner library, which is imported in the class StdIn, so it shouldn't be missing..?
import java.util.Scanner;
Here is the full code for class Graph (where the error occurs), if it helps!
Many thanks!
/*************************************************************************
* Compilation: javac Graph.java
* Dependencies: ST.java SET.java In.java
*
* Undirected graph data type implemented using a symbol table
* whose keys are vertices (String) and whose values are sets
* of neighbors (SET of Strings).
*
* Remarks
* -------
* - Parallel edges are not allowed
* - Self-loop are allowed
* - Adjacency lists store many different copies of the same
* String. You can use less memory by interning the strings.
*
*************************************************************************/
public class Graph {
// symbol table: key = string vertex, value = set of neighboring vertices
private ST<String, SET<String>> st;
// number of edges
private int E;
// create an empty graph
public Graph() {
st = new ST<String, SET<String>>();
}
// read a graph from an input stream
public Graph(In in, String delimiter) {
st = new ST<String, SET<String>>();
while (in.hasNextLine()) {
String line = in.readLine();
String[] names = line.split(delimiter);
for (int i = 1; i < names.length; i++) {
addEdge(names[0], names[i]);
}
}
}
// return number of vertices and edges
public int V() { return st.size(); }
public int E() { return E; }
// return the degree of vertex v
public int degree(String v) {
if (!st.contains(v)) return 0;
else return st.get(v).size();
}
// add w to v's set of neighbors, and add v to w's set of neighbors
public void addEdge(String v, String w) {
if (!hasEdge(v, w)) E++;
if (!hasVertex(v)) addVertex(v);
if (!hasVertex(w)) addVertex(w);
st.get(v).add(w);
st.get(w).add(v);
}
// add a new vertex v with no neighbors (if vertex does not yet exist)
public void addVertex(String v) {
if (!hasVertex(v)) st.put(v, new SET<String>());
}
// return iterator over all vertices in graph
public Iterable<String> vertices() {
return st;
}
// return an iterator over the neighbors of vertex v
public Iterable<String> adjacentTo(String v) {
// return empty set if vertex isn't in graph
if (!hasVertex(v)) return new SET<String>();
else return st.get(v);
}
// is v a vertex in the graph?
public boolean hasVertex(String v) {
return st.contains(v);
}
// is v-w an edge in the graph?
public boolean hasEdge(String v, String w) {
if (!hasVertex(v)) return false;
return st.get(v).contains(w);
}
// not very efficient, intended for debugging only
public String toString() {
String s = "";
for (String v : st) {
s += v + ": ";
for (String w : st.get(v)) {
s += w + " ";
}
s += "\n";
}
return s;
}
public static void main(String[] args) {
Graph G = new Graph();
G.addEdge("A", "B");
G.addEdge("A", "C");
G.addEdge("C", "D");
G.addEdge("D", "E");
G.addEdge("D", "G");
G.addEdge("E", "G");
G.addVertex("H");
// print out graph
StdOut.println(G);
// print out graph again by iterating over vertices and edges
for (String v : G.vertices()) {
StdOut.print(v + ": ");
for (String w : G.adjacentTo(v)) {
StdOut.print(w + " ");
}
StdOut.println();
}
}
}
And here is the class StdIn, again if it helps!
/*************************************************************************
* Compilation: javac StdIn.java
* Execution: java StdIn
*
* Reads in data of various types from standard input.
*
*************************************************************************/
import java.util.Scanner;
import java.util.Locale;
import java.io.BufferedInputStream;
/**
* <i>Standard input</i>. This class provides methods for reading strings
* and numbers from standard input.
* <p>
* The Locale used is: language = English, country = US. This is consistent
* with the formatting conventions with Java floating-point literals,
* command-line arguments (via <tt>Double.parseDouble()</tt>)
* and standard output (via <tt>System.out.print()</tt>). It ensures that
* standard input works the number formatting used in the textbook.
* <p>
* For additional documentation, see <a href="http://www.cs.princeton.edu/introcs/15inout">Section 1.5</a> of
* <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
*/
public final class StdIn {
// assume Unicode UTF-8 encoding
private static String charsetName = "UTF-8";
// assume language = English, country = US for consistency with System.out.
private static Locale usLocale = new Locale("en", "US");
// the scanner object
private static Scanner scanner = new Scanner(new BufferedInputStream(System.in), charsetName);
// static initializer
static { scanner.useLocale(usLocale); }
// singleton pattern - can't instantiate
private StdIn() { }
/**
* Is there only whitespace left on standard input?
*/
public static boolean isEmpty() {
return !scanner.hasNext();
}
/**
* Return next string from standard input
*/
public static String readString() {
return scanner.next();
}
/**
* Return next int from standard input
*/
public static int readInt() {
return scanner.nextInt();
}
/**
* Return next double from standard input
*/
public static double readDouble() {
return scanner.nextDouble();
}
/**
* Return next float from standard input
*/
public static float readFloat() {
return scanner.nextFloat();
}
/**
* Return next short from standard input
*/
public static short readShort() {
return scanner.nextShort();
}
/**
* Return next long from standard input
*/
public static long readLong() {
return scanner.nextLong();
}
/**
* Return next byte from standard input
*/
public static byte readByte() {
return scanner.nextByte();
}
/**
* Return next boolean from standard input, allowing "true" or "1" for true,
* and "false" or "0" for false
*/
public static boolean readBoolean() {
String s = readString();
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
if (s.equals("1")) return true;
if (s.equals("0")) return false;
throw new java.util.InputMismatchException();
}
/**
* Return rest of line from standard input
*/
public static String readLine() {
return scanner.nextLine();
}
/**
* Return next char from standard input
*/
// a complete hack and inefficient - email me if you have a better
public static char readChar() {
// (?s) for DOTALL mode so . matches a line termination character
// 1 says look only one character ahead
// consider precompiling the pattern
String s = scanner.findWithinHorizon("(?s).", 1);
return s.charAt(0);
}
/**
* Return rest of input from standard input
*/
public static String readAll() {
if (!scanner.hasNextLine()) return null;
// reference: http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
return scanner.useDelimiter("\\A").next();
}
/**
* Unit test
*/
public static void main(String[] args) {
System.out.println("Type a string: ");
String s = StdIn.readString();
System.out.println("Your string was: " + s);
System.out.println();
System.out.println("Type an int: ");
int a = StdIn.readInt();
System.out.println("Your int was: " + a);
System.out.println();
System.out.println("Type a boolean: ");
boolean b = StdIn.readBoolean();
System.out.println("Your boolean was: " + b);
System.out.println();
System.out.println("Type a double: ");
double c = StdIn.readDouble();
System.out.println("Your double was: " + c);
System.out.println();
}
}
And if needed, here is class In: (this is a bit lengthy sorry)
/*************************************************************************
* Compilation: javac In.java
* Execution: java In
*
* Reads in data of various types from: stdin, file, URL.
*
* % java In
*
* Remarks
* -------
* - isEmpty() returns true if there is no more input or
* it is all whitespace. This might lead to surprising behavior
* when used with readChar()
*
*************************************************************************/
import java.net.URLConnection;
import java.net.URL;
import java.net.Socket;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.util.Scanner;
import java.util.Locale;
import java.util.*;
import java.io.*;
/**
* <i>Input</i>. This class provides methods for reading strings
* and numbers from standard input, file input, URL, and socket.
* <p>
* The Locale used is: language = English, country = US. This is consistent
* with the formatting conventions with Java floating-point literals,
* command-line arguments (via <tt>Double.parseDouble()</tt>)
* and standard output (via <tt>System.out.print()</tt>). It ensures that
* standard input works the number formatting used in the textbook.
* <p>
* For additional documentation, see <a href="http://www.cs.princeton.edu/introcs/31datatype">Section 3.1</a> of
* <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
*/
public final class In {
private Scanner scanner;
// assume Unicode UTF-8 encoding
//private String charsetName = "UTF-8";
private String charsetName = "ISO-8859-1";
// assume language = English, country = US for consistency with System.out.
private Locale usLocale = new Locale("en", "US");
/**
* Create an input stream for standard input.
*/
public In() {
scanner = new Scanner(new BufferedInputStream(System.in), charsetName);
scanner.useLocale(usLocale);
}
/**
* Create an input stream from a socket.
*/
public In(Socket socket) {
try {
InputStream is = socket.getInputStream();
scanner = new Scanner(new BufferedInputStream(is), charsetName);
scanner.useLocale(usLocale);
}
catch (IOException ioe) {
System.err.println("Could not open " + socket);
}
}
/**
* Create an input stream from a URL.
*/
public In(URL url) {
try {
URLConnection site = url.openConnection();
InputStream is = site.getInputStream();
scanner = new Scanner(new BufferedInputStream(is), charsetName);
scanner.useLocale(usLocale);
}
catch (IOException ioe) {
System.err.println("Could not open " + url);
}
}
/**
* Create an input stream from a file or web page.
*/
public In(String s) {
try {
// first try to read file from local file system
File file = new File(s);
if (file.exists()) {
scanner = new Scanner(file, charsetName);
scanner.useLocale(usLocale);
return;
}
// next try for files included in jar
URL url = getClass().getResource(s);
// or URL from web
if (url == null) { url = new URL(s); }
URLConnection site = url.openConnection();
InputStream is = site.getInputStream();
scanner = new Scanner(new BufferedInputStream(is), charsetName);
scanner.useLocale(usLocale);
}
catch (IOException ioe) {
System.err.println("Could not open " + s);
}
}
/**
* Does the input stream exist?
*/
public boolean exists() {
return scanner != null;
}
/**
* Is the input stream empty?
*/
public boolean isEmpty() {
return !scanner.hasNext();
}
/**
* Read and return the next line.
*/
public String readLine() {
String line = null;
try { line = scanner.nextLine(); }
catch (Exception e) { }
return line;
}
/**
* Read and return the next character.
*/
public char readChar() {
// (?s) for DOTALL mode so . matches any character, including a line termination character
// 1 says look only one character ahead
// consider precompiling the pattern
String s = scanner.findWithinHorizon("(?s).", 1);
return s.charAt(0);
}
// return rest of input as string
/**
* Read and return the remainder of the input as a string.
*/
public String readAll() {
if (!scanner.hasNextLine()) { return null; }
// reference: http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
return scanner.useDelimiter("\\A").next();
}
/**
* Return the next string from the input stream.
*/
public String readString() {
return scanner.next();
}
/**
* Return the next int from the input stream.
*/
public int readInt() {
return scanner.nextInt();
}
/**
* Return the next double from the input stream.
*/
public double readDouble() {
return scanner.nextDouble();
}
/**
* Return the next float from the input stream.
*/
public double readFloat() {
return scanner.nextFloat();
}
/**
* Return the next long from the input stream.
*/
public long readLong() {
return scanner.nextLong();
}
/**
* Return the next byte from the input stream.
*/
public byte readByte() {
return scanner.nextByte();
}
/**
* Return the next boolean from the input stream, allowing "true" or "1"
* for true and "false" or "0" for false.
*/
public boolean readBoolean() {
String s = readString();
if (s.equalsIgnoreCase("true")) return true;
if (s.equalsIgnoreCase("false")) return false;
if (s.equals("1")) return true;
if (s.equals("0")) return false;
throw new java.util.InputMismatchException();
}
/**
* Close the input stream.
*/
public void close() { scanner.close(); }
/**
* Test client.
*/
public static void main(String[] args) {
In in;
String urlName = "http://www.cs.princeton.edu/IntroCS/stdlib/InTest.txt";
// read from a URL
System.out.println("readAll() from URL " + urlName);
System.out.println("---------------------------------------------------------------------------");
try {
in = new In(urlName);
System.out.println(in.readAll());
}
catch (Exception e) { }
System.out.println();
// read one line at a time from URL
System.out.println("readLine() from URL " + urlName);
System.out.println("---------------------------------------------------------------------------");
try {
in = new In(urlName);
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) { }
System.out.println();
// read one string at a time from URL
System.out.println("readString() from URL " + urlName);
System.out.println("---------------------------------------------------------------------------");
try {
in = new In(urlName);
while (!in.isEmpty()) {
String s = in.readString();
System.out.println(s);
}
}
catch (Exception e) { }
System.out.println();
// read one line at a time from file in current directory
System.out.println("readLine() from current directory");
System.out.println("---------------------------------------------------------------------------");
try {
in = new In("./InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) { }
System.out.println();
// read one line at a time from file using relative path
System.out.println("readLine() from relative path");
System.out.println("---------------------------------------------------------------------------");
try {
in = new In("../stdlib/InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) { }
System.out.println();
// read one char at a time
System.out.println("readChar() from file");
System.out.println("---------------------------------------------------------------------------");
try {
in = new In("InTest.txt");
while (!in.isEmpty()) {
char c = in.readChar();
System.out.print(c);
}
}
catch (Exception e) { }
System.out.println();
System.out.println();
// read one line at a time from absolute OS X / Linux path
System.out.println("readLine() from absolute OS X / Linux path");
System.out.println("---------------------------------------------------------------------------");
in = new In("/n/fs/csweb/introcs/stdlib/InTest.txt");
try {
while开发者_运维技巧 (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
}
catch (Exception e) { }
System.out.println();
// read one line at a time from absolute Windows path
System.out.println("readLine() from absolute Windows path");
System.out.println("---------------------------------------------------------------------------");
try {
in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");
while (!in.isEmpty()) {
String s = in.readLine();
System.out.println(s);
}
System.out.println();
}
catch (Exception e) { }
System.out.println();
}
}
Importing a class isn't the same as inheriting from it. It just means that the source file knows about that type.
If you're going to call foo.hasNextLine()
and expect the Scanner.hasNextLine()
method to be called, then the type of foo
must either be Scanner
or some subclass.
Your StdIn
class doesn't extend Scanner
- it contains a Scanner
. So one option would be to add an extra method to delegate the hasNextLine
method:
public static bool hasNextLine() {
return scanner.hasNextLine();
}
Note that this is a static method though, and shouldn't be called via a reference as you're doing in your original code:
while (in.hasNextLine()) {
that should be
while (StdIn.hasNextLine()) {
to make it clear that it's a static method - that it doesn't depend on the state of the object that in
refers to. Accessing a static member as if it were an instance member is legal Java, but bad practice.
(The same is true of your other calls through in
, of course. Given that it's just calling static methods, you don't need the parameter at all.)
Seems like you are missing a lot of import statements. You need to import all classes you are using except the ones in java.lang.
精彩评论