illegal start of type Java - java

I have a menu-driven program allows the user to add, remove and display the name of a person in a queue.
My program compiles and runs perfectly for me.
However, when my instructor tested it, he stated it won't compile and receives this error?:
QueueProgram.java:24: illegal start of type
MyQueue<String> queue= new MyQueue<>(15);
^
1 error
My code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;
public class QueueProgram {
/**
* Driver code to test class
*
* #param arguments
* Commandline arguments not used
* #throws IOException
*/
public static void main(String[] arguments) throws IOException {
//Queue Object
MyQueue<String> queue= new MyQueue<>(15);
String name;
//reading file
read(queue,arguments[0]);
String[] array = { "Offer Person", "Poll Person", "Peek person",
"Display Queue", "Exit Program"};
int choice = 0;
// display loop
while (choice != array.length-1) {
choice = JOptionPane.showOptionDialog(null, // put in center of screen
"Press a Button", // message to user
"Queue(Line) of People", // title of window
JOptionPane.YES_NO_CANCEL_OPTION, // type of option
JOptionPane.QUESTION_MESSAGE, // type of message
null, // icon
array, // array of strings
array[array.length - 1]); // default choice (last one)
if(choice==0){
//inserting the new name in queue
name=JOptionPane.showInputDialog(null,"Enter Person's name","Input");
queue.offer(name);
}
else if(choice==1){
//Display and remove the name which is at front of line
JOptionPane.showMessageDialog(null, queue.poll() + " is next in line");
}
else if(choice==2){
//Display name which is at front of line
JOptionPane.showMessageDialog(null, queue.peek() + " is front of the line");
}
else if(choice==3){
//Dispay all the list
JOptionPane.showMessageDialog(null, queue.toString());
}
//JOptionPane.showMessageDialog(null, "Your pressed button #" + choice);
}
//calling writing function
write(queue, arguments[1]);
}// end of main()
/**
* Reads a file
* #param queue
* #param file_name name of file
*/
public static void read(QueueInterface<String> queue, String file_name) throws IOException{
String name;
//creating a buffer reader to read
BufferedReader br= new BufferedReader(new FileReader(file_name));
while((name=br.readLine()) != null){
//putting in the queue
queue.offer(name);
}
//closing buffer reader
br.close();
}
/**
* Writes to file
* #param queue QueueInterface methods
* #param file_name name of file
*/
public static void write(QueueInterface<String> queue, String file_name) throws IOException{
String name;
//creating a buffer writer to write
BufferedWriter bw= new BufferedWriter(new FileWriter(file_name));
while((name=queue.poll()) != null){
//writin in file
bw.write(name);
bw.newLine();
}
//closing buffer
bw.close();
}
}// end of class
class MyQueue<T> extends ArrayQueue<T>{
/**
* Constructor
*
* #param max is the greatest number of elements in the queue
*/
public MyQueue(int max) {
super(max);
}
/**
* Returns a string representation of the object
*
* #return a name on different lines
*/
public String toString() {
// create a variable
String element = "";
int count=frontIndex;
// check to see if not empty
if (!this.empty()) {
// get the address of front element
while(count<=endIndex){
element = element +(String) array[count]+"\n";
count++;
}
}
// return either null or element
return element;
}
}
Any idea what could cause this error?

The diamond operator (<>) was introduced in Java 7 only. You should specify the type argument (new MyQueue<String>(15)) explicitly and your instructor will be able to compile it.
You can find the explanation here - Java SE 7 Features and Enhancements - Type Inference for Generic Instance Creation.

Related

How to put in a proper file path in java Eclipse

I would like to know how to properly put in a text file and then convert it to an HTML file.
When I try putting a text file I get the errors
java.security.InvalidParameterException: Configuration file unreadable.
at com.outsideinsdk.ExportTest.parseConfig(ExportTest.java:51)
at com.outsideinsdk.ExportTest.<init>(ExportTest.java:35)
at com.outsideinsdk.ExportTest.main(ExportTest.java:197)
Sample code below
package com.outsideinsdk;
import com.outsideinsdk.*;
import java.io.*;
import java.security.*;
import java.util.*;
/**
* The <code>ExportTest</code> class tests the {#link Export Export} technology
* according to the properties provided in a given configuration file. The
* configuration file is assumed to be correctly formatted.
*
* #author Kevin Glannon
* #version 1.00
* #see Export Export
*/
public class ExportTest
{
private static final String INPUTPATHKEY = "inputpath";
private static final String OUTPUTPATHKEY = "outputpath";
private static final String OUTPUTIDKEY = "outputid";
Properties configProps = new Properties();
/**
* Since <code>ExportTest</code> objects are always associated with a
* configuration file, the constructor requires a configuration file path.
*
* #param cfp The configuration file path.
*/
public ExportTest(String cfp)
throws FileNotFoundException, IOException
{
parseConfig(cfp);
}
/**
* Parse the configuration file specified by the given path.
*
* #param cfp The configuration file path.
*/
public void parseConfig(String cfp)
throws FileNotFoundException, IOException
{
// Assure the configuration file exists and is readable.
File cff = new File(cfp);
if (!cff.exists() || !cff.isFile() || !cff.canRead())
{
throw(new InvalidParameterException("Configuration file unreadable."));
}
BufferedReader cfr = new BufferedReader(new FileReader(cff));
String line;
// Loop over all lines from the file.
while ((line = cfr.readLine()) != null)
{
processLine(line);
}
}
/**
* Support the parsing of the configuration file by processing a given
* line.
*
* #param l A line from a configuration file.
*/
private void processLine(String l)
{
// Look for comments.
int indPound = l.indexOf('#');
// Remove comments and whitespace.
String line = (indPound == -1) ? l.trim() :
l.substring(0, indPound).trim();
if (line.length() != 0)
{
StringTokenizer stl = new StringTokenizer(line);
String key = stl.nextToken();
String value = stl.nextToken();
while(stl.hasMoreTokens())
{
value +=" " + stl.nextToken();
}
// Fill in the appropriate property.
configProps.setProperty(key, value);
}
}
/**
* Run the conversion using the given input path, output path.
*
* #param ifp Input path.
* #param ofp Output path.
* #param timeout Export process timeout in milliseconds.
*/
public void convert(String ifp, String ofp, long timeout)
{
String oid = configProps.getProperty(OUTPUTIDKEY);
// Display the parameters.
System.out.println("Input Path: "+ifp+" Output Path: "+ofp+
" Output ID: "+oid);
// Remove extra control properties.
configProps.remove(INPUTPATHKEY);
configProps.remove(OUTPUTPATHKEY);
// Create list of input files.
File iff = new File(ifp);
File [] iffa;
if (iff.isDirectory())
iffa = iff.listFiles();
else
{
iffa = new File[1];
iffa[0] = iff;
}
// Create output directory if needed. Assuming that if the input path
// is a directory, the output path should also be a directory.
File off = new File(ofp);
if (iff.isDirectory() && !off.exists()) off.mkdir();
// Process the conversion.
Export e = new Export(configProps);
if (off.isDirectory())
{
// The outputid is in the form fi_XXX where XXX is a reasonable
// extension so we take the extension for the oid.
// oid.substring(3) means to get the string following the fi_
String ext = "." + oid.substring(3);
for (int i=0; i<iffa.length; i++)
{
String ifn = iffa[i].toString();
String ofn = ofp + File.separator + iffa[i].getName() + ext;
System.out.println("Converting "+ifn+" to "+ofn);
ExportStatusCode result = e.convert(ifn, ofn, oid, timeout);
if (result.getCode() == ExportStatusCode.SCCERR_OK.getCode())
{
System.out.println("Conversion Successful!");
}
else {
System.out.println("Conversion Error: " + result);
}
}
}
else
{
for (int i=0; i<iffa.length; i++)
{
ExportStatusCode result = e.convert(iffa[i].toString(), ofp, oid, timeout);
if (result.getCode() == ExportStatusCode.SCCERR_OK.getCode())
{
System.out.println("Conversion Successful!");
}
else {
System.out.println("Conversion Error: " + result);
}
}
}
}
/**
* Run the test according to the given arguments. These arguments must adhere to the following usage.<br><br>
* Usage:<br>
* ExportTest InputPath OutputPath ConfigurationFile [Timeout]<br><br>
*
* InputPath and OutputPath may be single files or directories. If InputPath is a directory, then all files in
* that directory will be converted, but without recursion. If OutputPath is a directory, then all converted
* files from InputPath are placed in the OutputPath directory by appending an extension which represents the
* output file type. Timeout is in milliseconds.
*
* #param args Command line arguments.
*/
public static void main(String[] args)
{
int count = args.length;
// Check for specification of configuration file.
if (count != 3 && count != 4)
{
System.out.println("Input path, output path and configuration file are required.");
System.out.println("Usage: ExportTest InputPath OutputPath "+
"ConfigurationFile [Timeout(in milliseconds)]");
System.out.println();
}
else
{
ExportTest ct = null;
try
{
ct = new ExportTest(args[2]);
}
catch (Exception ex)
{
ex.printStackTrace();
return;
}
long timeout = 0;
if( count == 4 )
{
timeout = Integer.decode( args[3] ).longValue();
}
ct.convert(args[0], args[1], timeout);
}
}
}
This is how my program arguments look like: here
This is where the yes.txt files are located in the project called explorer: here

Run Java Console Input as Statement

I am writing a command-line matrix manipulation tool in Java, and was wondering if it is possible to run Java statements through console input.
I was thinking of using the java.util.Scanner object since that's what I'm using for the rest of my application, but I am open to any solution.
Here is a copy of my tool's application class, so you can see what I mean:
package projects.matrix.main;
import static java.lang.System.*;
import java.util.Scanner;
import projects.matrix.util.MatrixTool;
/**
* MATRIX :: Application class for the matrix toolset.
* #author toner
* #version May 28 2015
* #since 1.8
**/
public class MarixApp {
public static void main (String [] args) {
out.println("****************************** START*****************"
+ "*************\n");
runCommandLine();
out.println("****************************** END *****************"
+ "*************\n");
}
/**
* MATRIX.MAIN :: runCommandLine runs a loop command line
* #param none
* #return none
**/
public static void runCommandLine () {
// method vars
Scanner scanner = new Scanner(in);
MatrixTool matrixtool = new MatrixTool();
int[][] matrix1 = new int[0][0];
int[][] matrix2 = new int[0][0];
int[][] resultmatrix = new int[0][0];
String command = "";
int executerret = 0;
// welcome prints
out.println("[!] welcome to toner's matrix tool command-line");
out.println("[!] enter 'HELP' to view available commands\n");
// commmand-line loop
do {
out.print(" [?] >> ");
command = scanner.nextLine();
executerret = executecmd(command);
} while (executerret != -1);
}
/**
* MATRIX.MAIN :: executecmd executes the command passed by runCommandLine
* #param cmd : String
* #return returncode : int
**/
public static int executecmd (String cmd) {
// method vars
Scanner scanner = new Scanner(in);
MatrixTool matrixtool = new MatrixTool();
int returncode = 0;
// command executer
switch (cmd) {
case "HELP" :
case "help" :
out.println("\n"
+ " [%] ADD DIVIDE HELP "
+ "MULTIPLY PRINT"
+ " [%] RUNJAVA SUBSTRACT SETMTRX "
+ "SETMTRX1 SETMTRX2"
+ " [%] TRANSPOSE RUNOPS RESET "
+ "EXIT\n");
break;
// rest of commands go here
}
}
}
Regards.
Have you thought about using Groovy? It's a JVM based dynamic language which means you can dynamically execute code - code that comes as a String. Syntactically it's very close to Java. An example code could look like:
new GroovyShell().evaluate("println 'hello'")
If by running console input as java statements, you mean taking the exact input from the console and run it inside your application, you need to compile and run them. You can do so using the Compiler API

parallel file downloads using nio without creating threads per file download

I have tried a program which download files parallely using java.nio by creating a thread per file download.
package com.java.tftp.nio;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* This class is used to download files concurrently from tftp server by
* configuring the filenames, no of files.
*
* #author SHRIRAM
*
*/
public class TFTP_NIO_Client {
/**
* destination folder
* */
private String destinationFolder;
/**
* list of files names to download
* */
private List<String> fileNames;
/**
* integer indicates the number of files to download concurrently
* */
private int noOfFilesToDownload;
public TFTP_NIO_Client(List<String> fileNames, String destinationFolder,
int noOfFilesToDownload) {
this.destinationFolder = destinationFolder;
this.fileNames = fileNames;
this.noOfFilesToDownload = noOfFilesToDownload;
initializeHandlers();
}
/**
* This method creates threads to register the channel to process download
* files concurrently.
*
* #param noOfFilesToDownload
* - no of files to download
*/
private void initializeHandlers() {
for (int i = 0; i < noOfFilesToDownload; i++) {
try {
Selector aSelector = Selector.open();
SelectorHandler theSelectionHandler = new SelectorHandler(
aSelector, fileNames.get(i));
theSelectionHandler.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Setup RRQ/WRQ packet Packet : | Opcode | FileName | 0 | mode | 0 |
* Filename -> Filename in array of bytes. 0 -> indicates end of file mode
* -> string in byte array 'netascii' or 'octet'
*
* #param aOpcode
* #param aMode
* #param aFileName
* #throws IOException
*/
private void sendRequest(int aOpcode, int aMode, String aFileName,
DatagramChannel aChannel, InetSocketAddress aAddress)
throws IOException {
// Read request packet
TFTPReadRequestPacket theRequestPacket = new TFTPReadRequestPacket();
aChannel.send(
theRequestPacket.constructReadRequestPacket(aFileName, aMode),
aAddress);
}
/**
* sends TFTP ACK Packet Packet : | opcode | Block# | opcode -> 4 -> 2 bytes
* Block -> block number -> 2bytes
*
* #param aBlock
*/
private ByteBuffer sendAckPacket(int aBlockNumber) {
// acknowledge packet
TFTPAckPacket theAckPacket = new TFTPAckPacket();
return theAckPacket.getTFTPAckPacket(aBlockNumber);
}
/**
* This class is used to handle concurrent downloads from the server.
*
* */
public class SelectorHandler extends Thread {
private Selector selector;
private String fileName;
/**
* flag to indicate the file completion.
* */
private boolean isFileReadFinished = false;
public SelectorHandler(Selector aSelector, String aFileName)
throws IOException {
this.selector = aSelector;
this.fileName = aFileName;
registerChannel();
}
private void registerChannel() throws IOException {
DatagramChannel theChannel = DatagramChannel.open();
theChannel.configureBlocking(false);
selector.wakeup();
theChannel.register(selector, SelectionKey.OP_READ);
sendRequest(Constants.OP_READ, Constants.ASCII_MODE, fileName,
theChannel, new InetSocketAddress(Constants.HOST,
Constants.TFTP_PORT));
}
#Override
public void run() {
process();
}
private void process() {
System.out.println("Download started for " + fileName + " ");
File theFile = new File(destinationFolder
+ fileName.substring(fileName.lastIndexOf("/")));
FileOutputStream theFout = null;
try {
theFout = new FileOutputStream(theFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (!isFileReadFinished) {
try {
if (selector.select() == 0) {
try {
// sleep 2sec was introduced because selector is
// thread safe but keys are not thread safe
Thread.sleep(2000);
} catch (InterruptedException e) {
continue;
}
continue;
}
Set<SelectionKey> theSet = selector.selectedKeys();
Iterator<SelectionKey> theSelectedKeys = theSet.iterator();
synchronized (theSelectedKeys) {
while (theSelectedKeys.hasNext()) {
SelectionKey theKey = theSelectedKeys.next();
theSelectedKeys.remove();
if (theKey.isReadable()) {
isFileReadFinished = read(theKey, theFout,
fileName);
if (!isFileReadFinished) {
theKey.interestOps(SelectionKey.OP_READ);
}
} else if (theKey.isWritable()) {
// there is no implementation for file write to
// server.
theKey.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException ie) {
ie.printStackTrace();
}
}
System.out.println("Download finished for " + fileName);
try {
if (selector.isOpen()) {
selector.close();
}
if (theFout != null) {
theFout.close();
}
} catch (IOException ie) {
}
}
}
/**
* #param aKey
* registered key for the selector
* #param aOutStream
* - file output stream to write the file contents.
* #return boolean
* #throws IOException
*/
private boolean read(SelectionKey aKey, OutputStream aOutStream,
String aFileName) throws IOException {
DatagramChannel theChannel = (DatagramChannel) aKey.channel();
// data packet
TFTPDataPacket theDataPacket = new TFTPDataPacket();
ByteBuffer theReceivedBuffer = theDataPacket.constructTFTPDataPacket();
SocketAddress theSocketAddress = theChannel.receive(theReceivedBuffer);
theReceivedBuffer.flip();
byte[] theBuffer = theReceivedBuffer.array();
byte[] theDataBuffer = theDataPacket.getDataBlock();
if (theDataPacket.getOpCode() == Constants.OP_DATA) {
int theLimit = theDataPacket.getLimit();
// checks the limit of the buffer because a packet with data less
// than 512 bytes of content signals that it is the last packet in
// transmission for this particular file
if (theLimit != Constants.MAX_BUFFER_SIZE
&& theLimit < Constants.MAX_BUFFER_SIZE) {
byte[] theLastBlock = new byte[theLimit];
System.arraycopy(theBuffer, 0, theLastBlock, 0, theLimit);
// writes the lastblock
aOutStream.write(theLastBlock);
// sends an acknowledgment to the server using TFTP packet
// block number
theChannel
.send(sendAckPacket((((theBuffer[2] & 0xff) << 8) | (theBuffer[3] & 0xff))),
theSocketAddress);
if (theChannel.isOpen()) {
theChannel.close();
}
return true;
} else {
aOutStream.write(theDataBuffer);
// sends an acknowledgment to the server using TFTP packet
// block number
theChannel
.send(sendAckPacket((((theBuffer[2] & 0xff) << 8) | (theBuffer[3] & 0xff))),
theSocketAddress);
return false;
}
} else if (Integer.valueOf(theBuffer[1]) == Constants.OP_ERROR) {
System.out.println("File : " + aFileName + " not found ");
handleError(theReceivedBuffer);
}
return false;
}
/**
* This method handles the error packet received from Server.
*
* #param aBuffer
*/
private void handleError(ByteBuffer aBuffer) {
// Error packet
new TFTPErrorPacket(aBuffer);
}
}
Is it possible to download multiple files in parallel using java.nio by not creating a thread per file download? If yes can anybody suggest a solution to proceed further.
I would provide an approach to achieve what you are aiming for :
Let L the list of files to be downloaded.
Create a Map M which will hold the mapping of File name to be downloaded and the corresponding Selector instance.
For each file F in L
Get Selector SK from M corresponding to F
Process the state of the Selector by checking for any of the events being ready.
If processing is complete then set the Selector corresponding to F as null. This will help in identifying files
whose
processing is completed.Alternatively, you can remove F from
L; so that the next time you are looping you only process files that are not yet completely downloaded.
The above being said, I am curious to understand why you would want to attempt such a feat? If the thought process behind this requirement is to reduce the number of threads to 1 then it is not correct. Remember, you would end up really taxing the single thread running and for sure your throughput would not necessarily be optimal since the single thread would be dealing with both network as well as disk I/O. Also, consider the case of encountering an exception while writing one of the several files to the disk - you would end up aborting the transfer for all the files; something I am sure you do not want.
A better and more scalable approach would be to poll selectors on a single thread, but hand off any I/O activity to a worker thread. A better approach still would be to read the techniques presented in Doug Lea's paper and implement them. In fact Netty library already implements this pattern and is widely used in production.

ConcurrentModificationException exception with iterator in multithread chat server

I'm creating a multithread chat server in java.
When user u1 logs in and sends a message to user u2, if user u2 is not connected the message is sent to the server and put in an ArrayList of pending messages. When user u2 connects, he receive the message from the server and send a message to user u1 as a receipt.
This is my code:
if (pendingmsgs.size()>0) {
for(Iterator<String> itpendingmsgs = pendingmsgs.iterator(); itpendingmsgs.hasNext();) {
//....parsing of the message to get the recipient, sender and text
String pendingmsg = itpendingmsgs.next();
if (protocol.author != null && protocol.author.equals(recipient)) {
response+=msg;
protocol.sendMsg(sender, "Msg "+text+" sent to "+recipient);
itpendingmsgs.remove();
}
}
}
out.write(response.getBytes(), 0, response.length());
This is the ServerProtocol sendMsg() method:
private boolean sendMsg(String recip, String msg) throws IOException {
if (nicks.containsKey(recip)) { //if the recipient is logged in
ClientConnection c = nick.get(recipient); //get the client connection
c.sendMsg(msg); //sends the message
return true;
} else {
/* if the recipient is not logged in I save the message in the pending messages list */
pendingmsgs.add("From: "+nick+" to: "+recip+" text: "+msg);
return false;
}
}
and this is the ClientConnection sendMsg() method:
public void sendMsg(String msg) throws IOException {
out.write(msg.getBytes(), 0, msg.length());
}
where out is an OutputStream.
When user u1 logs in, sends a message to user u2 who is not logged in and then user u1 leaves, when user u2 logs in he doesn't receive the message and I get this exception:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at ChatServer$ClientConnection.run(ChatServer.java:400)
at java.lang.Thread.run(Unknown Source)
Line 400 is
itpendingmsgs.remove();
I've tried using a CopyOnWriteArrayList but it still doesn't work.
CopyOnWriteArrayList.iterator() doesn't support remove(). You should probably use a Collections.synchronizedList(ArrayList) (properly locked during iteration as specified in the Javadoc).
That's really the simplest way to allow one thread to add to the list and the other to iterate through removing elements.
Most probably after looking at your code, issue seems to be that while you are looping through your iterator you add new content to the ArrayList in sendMsg method
protocol.sendMsg(sender, "Msg "+text+" sent to "+recipient); // this line invokes the code which adds
pendingmsgs.add("From: "+nick+" to: "+recip+" text: "+msg); // this line adds a new item
See this discussion for reason why this happened last time around.
Edit: As per comment
line 400 is itpendingmsgs.remove();
This is definitely because of addition in the list, as when you reach itpendingmsgs.remove();, you have already added a new entry in the list which makes your iterator complain.
Update:
Appraches to fix this issue:
Instead of Iterator use ListIterator and add, remove objects from the ListIterator and not underlying List.
Update Sample Code :
package com.mumz.test.listiterator;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Random;
/**
* Test Class to show case List Iterator.
*/
public class TestListIterator {
/** The pendingmsgs. */
List<String> pendingmsgs = new ArrayList<String>();
/**
* Add some content to the list and then start processing the same list.
*/
private void init() {
addContentToList();
doProcessing();
}
/**
* Add test content to list.
*/
private void addContentToList() {
for (int iDx = 0; iDx < 10; iDx++) {
pendingmsgs.add("Message " + iDx);
}
}
/**
* Randomly decide if message should be added or removed, showcase iteration using list iterator.
*/
private void doProcessing() {
if (pendingmsgs.size() > 0) {
for(ListIterator<String> listIterator = pendingmsgs.listIterator(); listIterator.hasNext();){
String currentMessage = listIterator.next();
Random random = new Random();
int nextInt = random.nextInt(100);
if((nextInt % 2) == 0){
sendMsg(currentMessage, listIterator);
} else {
listIterator.remove();
}
}
}
}
/**
* Add new content to the list using listIterator of the underlying list.
*
* #param msg
* the msg
* #param listIterator
* the list iterator
* #return true, if successful
*/
private boolean sendMsg(String msg, ListIterator<String> listIterator) {
Random random = new Random();
int nextInt = random.nextInt(10);
// Randomly add new message to list
if ((nextInt % 2) == 0) {
listIterator.add("New Messsage : " + msg);
return false;
}
return true;
}
/**
* The main method.
*
* #param args
* the arguments
*/
public static void main(String[] args) {
try {
TestListIterator testListIterator = new TestListIterator();
testListIterator.init();
System.out.println(testListIterator);
} catch (Exception e) {
e.printStackTrace();
}
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
return String.format("TestListIterator [pendingmsgs=%s]", pendingmsgs);
}
}
Instead of using Iterator or ListIterator just use normal for or while loop, in this case you can directly modify your collection (list in this case) without getting this exception.
Use Iterator itself but dont add new elements into the list while you are looping.
Add your messages to another list say tempMessageHolder so sendMsg will add message to this list.
Once your loop is complete, add all the messages from tempMessageHolder to your main list pendingmsgs

Java pairs of symbols program

Using stack data structure(s): If the input file is not balanced, the un-balance cause and the in-file localization details will be supplied. For flexibility reasons, read the balancing pairs of symbols from a text file. Test your program by considering the following pairs of symbols: ( ), { }, [ ], /* */
I'm having trouble with the last requirement: /* */
I also can't seem to grasp how to print the in-file localization details? i.e which line number of the text file the error has occured on?
The text file looks like this:
(()(()
{}}}{}{
[[[]][][]
((}})){{]
()
[]
{}
[]{}
()()()[]
*/ /*
(a+b) = c
The code:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class P1 {
private boolean match = true;
// The stack
private java.util.Stack<Character> matchStack = new java.util.Stack<Character>();
// What to do with a match
public boolean ismatch() {
return match && matchStack.isEmpty();
}
// Finding a match
public void add(char c) {
Character k = leftSide(c);
if (k == null)
;
else if (k.charValue() == c)
matchStack.push(k);
else {
if (matchStack.isEmpty() || !matchStack.pop().equals(k))
match = false;
}
}
// Add string values
public void add(String s) {
for (int i = 0; i < s.length(); i++)
add(s.charAt(i));
}
// The various symbol pairs
protected static Character leftSide(char c) {
switch (c) {
case '(':
case ')':
return new Character('(');
case '[':
case ']':
return new Character('[');
case '{':
case '}':
return new Character('{');
default:
return null;
}
}
// Main method. Welcome message, read the test file, build the array, print
// results.
public static void main(String args[]) {
List<String[]> arrays = new ArrayList<String[]>();
// Welcome message
System.out
.println("Project #1\n"
+ "Welcome! The following program ensures both elements of various paired symbols are present.\n"
+ "Test Data will appear below: \n"
+ "-------------------------------");
// Read the file
try {
BufferedReader in = new BufferedReader(new FileReader(
"testfile.txt"));
String str;
// Keep reading while there is still more data
while ((str = in.readLine()) != null) {
// Line by line read & add to array
String arr[] = str.split(" ");
if (arr.length > 0)
arrays.add(arr);
// Let the user know the match status (i.e. print the results)
P1 mp = new P1();
mp.add(str);
System.out.print(mp.ismatch() ? "\nSuccessful Match:\n"
: "\nThis match is not complete:\n");
System.out.println(str);
}
in.close();
// Catch exceptions
} catch (FileNotFoundException e) {
System.out
.println("We're sorry, we are unable to find that file: \n"
+ e.getMessage());
} catch (IOException e) {
System.out
.println("We're sorry, we are unable to read that file: \n"
+ e.getMessage());
}
}
}
An easy way to implement this would be using a map of stacks such as Map<String, Stack<Location>>, where Location is a class you create that holds two ints (a line number and a character number). That can be your location info. The key (String) to this map would be your left side (opener) part of your pairs. Every time you have an opener you look up the appropriate Stack in the map and push a new Location on it for that opener. Each time you encounter a closer you look up its opener, use the opener to look up the correct Stack in the map and then pop it once. The reason I say use String for your key is because not all your openers can be represented by Character namely your /* opener, so a String will have to do. Since you can't switch on Strings for your leftSide(char) (which will now be leftSide(String)) function you'll either have to use if-else or use a map (Map<String, String>) to create the closer to opener mappings.
When the end of the file is reached the only Location objects remaining in the Stack objects should be unclosed openers.

Categories

Resources