Calling Two Different Methods into One Method in Java - java

I wish to:
Reading in two files
Split the files into individual strings
Compare the two string lists and retrieve strings that are unique to a file.
At the moment I am running in to the problem of finding a way to call the two methods used to call in the files (one for each file) to the same method in order to be compared.
Both methods use a try-catch-while statement and if I try to read all of the entries after the while statement only a single is shown and not the entire list.
Is there a way to send parts of both methods as parameter to a single new method?
Here is the code for the program. I know that there are problems with the way that I am doing the program, but I am only doing it the way that I was taught.
File mainEmails = new File("Testrun.txt");
Scanner inputScanner = null;
int counter = 1;
String fullName = null;
String position = null;
String companyName = null;
String telNumber = null;
String emailAddress = null;
try
{
inputScanner = new Scanner(mainEmails);
}
catch(FileNotFoundException e)
{
System.out.println("File has not been found.");
}
while (inputScanner.hasNextLine())
{
String nextLine = inputScanner.nextLine();
String [] splitFile = nextLine.split(",");
for (int i = 0; i <splitFile.length;i++)
{
if(i==0)
{
fullName = splitFile[0];
}
else if(i==1)
{
position = splitFile[1];
}
else if(i==2)
{
companyName = splitFile[2];
}
else if(i==3)
{
telNumber = splitFile[3];
}
else if(i==4)
{
emailAddress = splitFile[4];
}
else if(splitFile[i] == null)
{
System.out.println("You have failed!");
}
}
}
public static void deletionList()
{
File deletionEmails = new File("Testrun1.txt");
Scanner inputScanner1 = null;
String deletionfullName = null;
String deletionposition = null;
String deletioncompanyName= null;
String deletiontelNumber = null;
String deletionemailAddress = null;
try
{
inputScanner1 = new Scanner(deletionEmails);
}
catch(FileNotFoundException e)
{
System.out.println("File has not been found.");
}
while (inputScanner1.hasNextLine())
{
String deletionnextLine = inputScanner1.nextLine();
String [] deletionsplitFile = deletionnextLine.split(",");
for (int i = 0; i <deletionsplitFile.length;i++)
{
if(i==0)
{
deletionfullName = deletionsplitFile[0];
}
else if(i==1)
{
deletionposition = deletionsplitFile[1];
}
else if(i==2)
{
deletioncompanyName = deletionsplitFile[2];
}
else if(i==3)
{
deletiontelNumber = deletionsplitFile[3];
}
else if(i==4)
{
deletionemailAddress = deletionsplitFile[4];
}
else if(deletionsplitFile[i] == null)
{
System.out.println("You have failed!");
}
}
}
}
What I am trying to do is to take the fullName, emailAddress from the first split and deletionfullName and deletionemailAddress from the second split and compare the first and second of each, respectively. Each file will have a number of fields in it, and I am only interested in the fullName and emailAddress fields.

It is quite confusing to understand how you are trying to implement your solution, so may I suggest you look at a different way of doing the whole read-and-compare process. For example, I would suggest doing something like this... (in psuedocode)
public void compareFiles(String file1, String file2){
// Read the lines of each file into String[] arrays
String[] file1Lines = readAndSplitIntoLines(file1);
String[] file2Lines = readAndSplitIntoLines(file2);
// compare the lines
for (int x=0;x<file1Lines.length;x++){
for (int y=0;y<file2Lines.length;y++){
if (file1Lines[x].equals(file2Lines[y])){
// match. set it to null
file1Lines[x] = null;
file2Lines[y] = null;
// break out of the inner loop and start comparing the next line
break;
}
}
// remove the duplicates (which are now null values), creating a smaller array of uniques.
String[] newFile1 = shrinkArrayByRemovingNulls(file1Lines);
String[] newFile2 = shrinkArrayByRemovingNulls(file2Lines);
}

Besides the fact that your question is not very clear, you have at least one glaring problem:
DO NOT use exception handling for logic! Exception handling should be only for exceptions.
Secondly, think about what you are really looking to do. In pseudocode it would look something like this:
list1 = split(file(name1).read())
list2 = split(file(name2).read())
list3 = unique(list1, list2)
What does your code look like?

Related

Java parsing multiple files

I need to parse multiple files and get access to the object's methods outside of where they were initialized.
This is my code:
public static void main(String[] args) {
try {
File Attrationfile = new File("attractions.txt");
Scanner attractionscanner = null;
attractionscanner = new Scanner(Attrationfile);
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
String type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
RollerCoaster rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
File Customerfile = new File("customers.txt");
Scanner Customerscanner = new Scanner(Customerfile);
while (Customerscanner.hasNext()) {
String nextline = Customerscanner.nextLine();
String[] Customercomponents = nextline.split("#");
int accountnumber =Integer.parseInt(Customercomponents[0]);
String name = Customercomponents[1];
int age = Integer.parseInt(Customercomponents[2]) ;
int balance = Integer.parseInt(Customercomponents[3]) ;
String discount = Customercomponents.length <= 4
? String.valueOf(0) : Customercomponents[4];
Customer customer= new Customer(accountnumber,name, age, balance, discount);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
This works but I can't get access to the objects outside of their loops. I am not sure how the Сustomer class would get information about the roller coaster, such as the name and price. For example, if the customer and rollercoaster objects were in the same area, I would be able to update the customer balance by taking away rollercoaster.getprice from the customer.getbalance, and setting customer.setbalance to the value of the calculation. As you have probably already gathered, I am a beginner, so I am probably going about this in the wrong way - thanks.
You can change the scope for those variables by declaring them at the start of the main method.
public static void main(String[] args) {
Customer customer = null;
RollerCoaster rollerCoaster = null;
try {
File Attrationfile = new File("attractions.txt");
Scanner attractionscanner = null;
attractionscanner = new Scanner(Attrationfile);
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
String type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
File Customerfile = new File("customers.txt");
Scanner Customerscanner = new Scanner(Customerfile);
while (Customerscanner.hasNext()) {
String nextline = Customerscanner.nextLine();
String[] Customercomponents = nextline.split("#");
int accountnumber =Integer.parseInt(Customercomponents[0]);
String name = Customercomponents[1];
int age = Integer.parseInt(Customercomponents[2]) ;
int balance = Integer.parseInt(Customercomponents[3]) ;
String discount = Customercomponents.length <= 4 ? String.valueOf(0) :
Customercomponents[4];
customer= new Customer(accountnumber,name , age , balance, discount);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Welcome to SO! As Hovercraft pointed out, the objects are declared within the scope of the loop, meaning you can't access them outside of it as you noticed. Also, they are overwritten on every iteration, since you declare and initialize the object on every pass. Consider using an ArrayList like so (here just for the customers):
ArrayList<Customer> customerList = new ArrayList<>();
try {
while (customerScanner.hasNext()) {
// ...
customerList.add(new Customer(accountnumber,name, age, balance, discount));
}
} catch (...) {
// ...
}
Here's the doc for the ArrayList. <T> is a generic type, which for you means that you can have an ArrayList<Customer>, ArrayList<RollerCoaster>, ArrayList<String> ...
Sidenote: By convention, variable names start with a lowercase letter, like Scanner customerScanner instead of Scanner Customerscanner.
Is it a question of scope? Try to declare an object outside the body of the loop.
Because in Java, the brace is a scope. The more nested braces, the smaller the scope. You can try to declare the objects you need to call in the external scope in the same or larger scope
String type = null;
RollerCoaster rollerCoaster = null;
while (attractionscanner.hasNext()) {
String nextline = attractionscanner.nextLine();
String[] Attractioncomponents = nextline.split("#");
String ridename =Attractioncomponents[0];
int price = Integer.parseInt(Attractioncomponents[1]);
type = Attractioncomponents[2];
int unknown = Integer.parseInt(Attractioncomponents[3]) ;
double speed = Attractioncomponents.length <= 4 ? 0 :
Double.parseDouble(Attractioncomponents[4]);
rollerCoaster = new RollerCoaster(ridename, price , unknown, speed);
}

Alternate for multiple try catch to handle the exception

I am trying to read a CSV file with 20 columns which may or may not contain value but the problem is that I have to create 20 try catch in order to maintain the code flow in control manner. Like
String a = ""; loop
try{
a = list.get(0); // converted the csv to list of list and iterated in
}catch(NoSuchElementException e){}
and same for every other variable.The reason I have seperate try catch because In the below code
String a = "";
String b = "";
try{
a = list.get(0);
b = list.get(1);
}catch(NoSuchElementException e){}
If first line of try gave exception the second line will not execute.
So is there any alternate to these n number of try catch situation?
Thanks
You could create a helper method:
private String getField(List<String> list, int n) {
try {
return list.get(n);
} catch (NoSuchElementException e) {
return "";
}
}
String a = getField(list, 0);
String b = getField(list, 1);
EDIT:
Typically you wouldn't rely on exceptions if you do not have sufficient fields, the following achieves the same thing but subjectively feels cleaner:
private String getField(List<String> list, int n) {
if (n < list.size()) {
return list.get(n);
}
return "";
}

Exception organization assistance?

I had some success with this site, and I hope I find more excellent programmers to assist me.
So I am at my wit's end with this code. I am very new to programming, especially exceptions. I have looked very hard through my course material and sought help, but I have been quite unsuccessful. I am trying to create an improved parser that will override another parser. It reads a .txt file with student information of it including an ID, a name, a grade, and an optional email address and optional comment as tokens in a String separated by commas. The override checks for errors in each token and throws an exception called ParserException. The exception will check the code and then return an error message if the error is unfixable.
For example, if a student puts in an AB for the grade, the exception will flag and check if the input is a valid grade (which it is) and then return, if it is not, then it will throw a ParserException, in this case
throw new ParserException(ParserException.GRADE_INVALID_GRADE,lineIndex);
This shows that the does not work and sends out a message GRADE_INVALID on the line indexLine
I have a list of what I need to have as an output:
Any violation of the file format specified in the Input File Format Description section above should result in an ParcerException with an appropriate message
Duplicate IDs are not allowed
Grade values must be a float (92.0) or a letter grade and not an integer
I have all the code to correct and check for errors, but I cannot figure out how to get the try-catch to work. Here's is the override code:
#Override
public ParserResult parseLine(int lineIndex) {
String[] tokens = lines.get(lineIndex).split(",");
ArrayList<Integer> idList = new ArrayList<Integer>();
Integer studentId;
String name;
String grade;
String email;
String comments;
boolean isFloat;
float gradeFinal;
String editName;
studentId = new Integer(tokens[0]);
ParserResult result;
try{
return super.parseLine(lineIndex);
}
catch(ParserException e){
// Check reasonable number of tokens
if(tokens.length >= 3 && tokens.length <= 5){
name = tokens[1];
grade = tokens[2];
// Check the student ID
if(idList.contains(studentId)){
throw new ParserException(ParserException.DUPLICATE_ID, lineIndex);
}else{
idList.add(studentId);
}
// Check the grade
if(grade.trim().equalsIgnoreCase("A")){
gradeFinal = gradeA;
}else if(grade.trim().equalsIgnoreCase("AB")){
gradeFinal = gradeAB;
}else if(grade.trim().equalsIgnoreCase("B")){
gradeFinal = gradeB;
}else if(grade.trim().equalsIgnoreCase("BC")){
gradeFinal = gradeBC;
}else if(grade.trim().equalsIgnoreCase("C")){
gradeFinal = gradeC;
}else if(grade.trim().equalsIgnoreCase("CD")){
gradeFinal = gradeCD;
}else if(grade.trim().equalsIgnoreCase("D")){
gradeFinal = gradeD;
}else if(grade.trim().equalsIgnoreCase("F")){
gradeFinal = gradeF;
}else{
try{
Integer.parseInt(grade);
isFloat = false;
}
catch(Exception fl) {
isFloat = true;
}
if(isFloat){
if((Float.parseFloat(grade) < 100f) && (Float.parseFloat(grade) >= 0f)){
gradeFinal = Float.parseFloat(grade);
}else{
throw new ParserException(ParserException.GRADE_INVALID_GRADE,lineIndex);
}
}else{
throw new ParserException(ParserException.GRADE_INTEGER_VALUE,lineIndex);
}
}
// Check the name
if(name.split(" ").length > 3){
throw new ParserException(ParserException.UNKNOWN, lineIndex);
}else{
editName = name.trim().split(" ")[0];
}
result = new ParserResult(studentId, editName, gradeFinal);
// Checks the email
if(tokens.length >= 4){
email = tokens[3];
// Check for at sign
if(!email.contains("#")){
throw new ParserException(ParserException.UNKNOWN, lineIndex);
}
int count = 0;
// Counts number of # symbols
for(int i=0; i<email.length(); i++){
if(email.indexOf(i) == '#'){
count++;
}
}
if(count > 1){
throw new ParserException(ParserException.EMAIL_MULTIPLE_AT,lineIndex);
}
if(email.split(".").length == 2){
if(!(email.trim().split(".")[1].contains(".edu")) && !(email.trim().split(".")[1].contains(".com"))){
throw new ParserException(ParserException.EMAIL_NOT_EDU_OR_COM,lineIndex);
}else{
result.setEmail(email);
}
}
// Checks if email contains .com or .edu
// Checks the comments
if(tokens.length == 5){
comments = tokens[4];
result.setComment(comments);
}
}
return result;
}
}
// TODO Call Parser's parseLine() here to attempt to parse, catch any exceptions
return null;
}
The original parseLine that is overridden, but still used is:
public ParserResult parseLine(int lineIndex) {
String[] tokens = lines.get(lineIndex).split(",");
ParserResult result = new ParserResult(Integer.parseInt(tokens[0]),
tokens[1], Float.parseFloat(tokens[2]));
result.setEmail(tokens[3]);
return result;
}
Here is the main() file:
public static void main(String[] args){
// TODO Change the line below to use ImprovedParser
Parser parser = null;
try {
parser = new ImprovedParser(args[0]);
} catch (FileNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
System.exit(-1);
}
List<ParserResult> results = parser.parse();
int count = results.size();
double sum = 0.0;
for (ParserResult result : results) {
sum += result.getGrade();
}
System.out.println("Number of valid input lines: " + results.size());
System.out.println("Number of invalid input lines: "
+ (parser.getLineCount() - results.size()));
System.out.println("Average grade: " + sum / count);
for (ParserResult result : results) {
System.out.println(result);
}
}
Lastly, here is the .txt file that is being read:
# student_id,name,grade,email
1234,Bob,92.0,bob#test.edu
4321,Alice,95.0,alice#test.edu
1111,Eve,80.0,eve#test.edu
1121,Barry,85.0,barrytest.edu
1131,Harry,86.0,h#rry#test.edu
1121,Larry,87.0,larry#test.edu
1141,Jim Song,88.0,jim#song.edu
1151,Jerry,77.0,jerry#test.net
1161,James,65.0,james#test.com
The last six inputs should cause exceptions, but I can't figure out how to organize it to work. The code ignores the line with # symbol.
Here is a sample successful output:
Number of valid input lines: 3
Number of invalid input lines: 0
Average grade: 89.0
1234, 92.0, Bob, bob#test.edu,
4321, 95.0, Alice, alice#test.edu,
1111, 80.0, Eve, eve#test.edu,
The major changes should be in the orverride method
Please help if you can, I sit at my desk still pondering possibilities, and your help will be most-appreciated.
Assuming ParseException has an error field being an int and someMethod() that throws ParseException:
try {
someMethod();
} catch (final ParseExeption ex) {
if (ex.getError() == ParseException.SOME_ERROR) {
// do something
} else if (ex.getError() == ParseException.OTHER_ERROR) {
// do something else
}
}
Note that it's usually better to use specific exceptions for specific error, something like SomeErrorParseException, OtherErrorParseException, ... (those can extends ParseException if you want) and try-catch like this:
try {
someMethod();
} catch (final SomeErrorParseException ex) {
// do something
} catch (final OtherErrorParseException ex) {
// do something else
}
Some reading: http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
It seems that there is no code to actually cause the catch clause in the first place. Try adding a throw new ParserException(STUFF_HERE); when an error has been detected while reading the file.

Constantly getting NullPointerException

I am making a program in which it encrypts words into some kind of secret message, but I keep on getting an error. Yes, I know the code is ugly... but I am a beginner.
Here is my main.
public class Main {
public static void main (String args []){
String message;
message = JOptionPane.showInputDialog("Give me something to crypt!");
Crypt secret = new Crypt();
secret.CyptedMessage(message);
}
}
Here is my class.
public class Crypt {
String letter[];
String message;
public Crypt(){
message = "";
letter[0]="A";
letter[1]="B";
letter[2]="C";
letter[3]="D";
letter[4]="E";
letter[5]="F";
letter[6]="G";
letter[7]="H";
letter[8]="I";
letter[9]="J";
letter[10]="K";
letter[11]="L";
letter[12]="M";
letter[13]="N";
letter[14]="O";
letter[15]="P";
letter[16]="Q";
letter[17]="R";
letter[18]="S";
letter[19]="T";
letter[20]="U";
letter[21]="V";
letter[22]="W";
letter[23]="X";
letter[24]="Y";
letter[25]="Z";
letter[26]=" ";
}
int getRandomCrypt(){
//Random number 1 to 25
int x;
x=(int)(1 + Math.random()*25);
return x;
}
int checkLetter(String subMessage){
//Checks letters
boolean b = false;
int i=0;
while (b = false){
if (i == 27){
i=0;
if (subMessage == letter[i])
return i;
else
i++;
}
}
return 0;
}
void CyptedMessage(String message){
String CyptedMessage = null;
String message1;
for (int i = 0; i < message.length(); i++){
int number = checkLetter(message.substring(i, i+1));
message1 = letter[number + getRandomCrypt()];
if (number + getRandomCrypt()>26){
message1 = letter[i-27];
}
CyptedMessage += message1;
}
System.out.print(CyptedMessage);
}
}
When I run this I get...
Exception in thread "main" java.lang.NullPointerException
at Crypt.<init>(Crypt.java:9)
at Main.main(Main.java:9)
As Serge pointed out, String letter[] is an array declaration, not an initialization. You need to then initialize it to define an exact size.
public Crypt(){
letter = new String[27]; //define array
message = "";
letter[0]="A";
letter[1]="B";
letter[2]="C";
letter[3]="D";
letter[4]="E";
letter[5]="F";
letter[6]="G";
letter[7]="H";
letter[8]="I";
letter[9]="J";
letter[10]="K";
letter[11]="L";
letter[12]="M";
letter[13]="N";
letter[14]="O";
letter[15]="P";
letter[16]="Q";
letter[17]="R";
letter[18]="S";
letter[19]="T";
letter[20]="U";
letter[21]="V";
letter[22]="W";
letter[23]="X";
letter[24]="Y";
letter[25]="Z";
letter[26]=" ";
}
Edit: forgot ;
And others beat me :P
You are not initializing your String letter[]; and directly adding values into it
do this in your constructor
letter = new String[size];
or do this in starting String letter[] = new String[size];
and in your case size is 27
You need to initialize you array ans not just define it.
String letter[] = new String[27];
Also you can put a NPE check before using the array data
if(letter[number + getRandomCrypt()] != null)
message1 = letter[number + getRandomCrypt()];
Your String letter[]; is not instantiated.
add letter = new String[size]; in your Constructor of Crypt before initialization.
In class Crypt, you declare a string array named letters, but you do not initialize it when you use it. That is why you encounter a NullPointerException.
Initilize it before you use it.
public Crypt(){
**letter= new String[27];**
letter[0]="A";
letter[1]="B";
... ...
}

Converting Java code into Groovy

I am trying to convert a Java function into equivalent Groovy code, but I am not able to find anything which does && operation in loop. Can anyone guide me through..
So far this is what I got
public List getAlert(def searchParameters, def numOfResult) throws UnsupportedEncodingException
{
List respList=null
respList = new ArrayList()
String[] searchStrings = searchParameters.split(",")
try
{
for(strIndex in searchStrings)
{
IQueryResult result = search(searchStrings[strIndex])
if(result!=null)
{
def count = 0
/*The below line gives me error*/
for(it in result.document && count < numOfResult)
{
}
}
}
}
catch(Exception e)
{
e.printStackTrace()
}
}
My Java code
public List getAlert(String searchParameters, int numOfResult) throws UnsupportedEncodingException
{
List respList = null
respList = new ArrayList()
String[] searchStrings = searchParameters.split(",")
try {
for (int strIndex = 0; strIndex < searchStrings.length; strIndex++) {
IQueryResult result = search(searchStrings[strIndex])
if (result != null) {
ListIterator it = result.documents()
int count = 0
while ((it.hasNext()) && (count < numOfResult)) {
IDocumentSummary summary = (IDocumentSummary)it.next()
if (summary != null) {
String docid = summary.getSummaryField("infadocid").getStringValue()
int index = docid.indexOf("#")
docid = docid.substring(index + 1)
String url = summary.getSummaryField("url").getStringValue()
int i = url.indexOf("/", 8)
String endURL = url.substring(i + 1, url.length())
String body = summary.getSummaryField("infadocumenttitle").getStringValue()
String frontURL = produrl + endURL
String strURL
strURL = frontURL
strURL = body
String strDocId
strDocId = frontURL
strDocId = docid
count++
}
}
}
result = null
}
} catch (Exception e) {
e.printStackTrace()
return respList
}
return respList
}
It seems to me like
def summary = result.documents.first()
if (summary) {
String docid = summary.getSummaryField("infadocid").getStringValue()
...
strDocId = docid
}
is all you really need, because the for loop actually doesn't make much sense when all you want is to process the first record.
If there is a possibility that result.documents contains nulls, then replace first() with find()
Edit: To process more than one result:
def summaries = result.documents.take(numOfResult)
// above code assumes result.documents contains no nulls; otherwise:
// def count=0
// def summaries = result.documents.findAll { it && count++<numOfResult }
summaries.each { summary ->
String docid = summary.getSummaryField("infadocid").getStringValue()
...
strDocId = docid
}
In idiomatic Groovy code, many loops are replace by iterating methods like each()
You know the while statement also exists in Groovy ?
As a consequence, there is no reason to transform it into a for loop.
/*The below line gives me error*/
for(it in result.document && count < 1)
{
}
This line is giving you an error, because result.document will try to call result.getDocument() which doesn't exist.
Also, you should avoid using it as a variable name in Groovy, because within the scope of a closure it is the default name of the first closure parameter.
I haven't looked at the code thoroughly (or as the kids say, "tl;dr"), but I suspect if you just rename the file from .java to .groovy, it will probably work.

Categories

Resources