Add up Figures in Different Files for same Customer Named - java

I have a requirement where I have Multiple Customer Invoices as different files. I am able to read the Customer Name and the Invoice Amount from each Invoice. The requirement is that for one customer, I should add up all the invoice amounts.
Here Is My Code:
String[] filenames1 = laf.splitFileNames();
FileInputStream fs;
BufferedReader br;
String line;
for (String filename1 : filenames1) {
fs = new FileInputStream(outFolder + filename1);
br = new BufferedReader(new InputStreamReader(fs));
for (int m = 0; m < 1; m++) {
br.readLine();
}
line = br.readLine().trim();
String cust_name = line.substring(12);//Returns the Customer Name
String amount = rll.lastNonBlankLine(new File(outFolder + filename1));//Returns Invoice Amount in String format
System.out.println(cust_name + "-" + rll.lastNonBlankLine(new File(outFolder + filename1)));
}
My Out put:
TAITA TAVETA TEACHERS SACCO-25,101.53
TAITA TAVETA TEACHERS SACCO-12,927.62
TAITA TAVETA TEACHERS SACCO-12,927.62
NOT FOR CUSTOMER-12,927.62
Ideally I should be able to get:
TAITA TAVETA TEACHERS SACCO-50,956.77
NOT FOR CUSTOMER-12,927.62
Please assists at this point where I am stuck.

You would have to somehow parse the amount string into some number type, probably BigDecimal. Then you could keep a Map from customer names to the current sum, which you continually update, while you read values.
Only when you are done reading in the files, you would then output the accumulated sums.
So you next steps should be:
Look up the reference documentation for BigDecimal, looking for a way to parse them.
Look up the reference documentation of Map, figuring out how they work and how that would help you.

I don't really think if this really help bu i should say, that your problem maybe when Returns Invoice Amount in String format, you do:
String amount = rll.lastNonBlankLine(new File(outFolder + filename1));
but when you print it, you will get another Invoice amount:
System.out.println(cust_name + "-" + rll.lastNonBlankLine(new File(outFolder + filename1)));
I think You have to do something like:
System.out.println(cust_name + "-" + amount);

Related

Java - String splitting

I read a txt with data in the following format: Name Address Hobbies
Example(Bob Smith ABC Street Swimming)
and Assigned it into String z
Then I used z.split to separate each field using " " as the delimiter(space) but it separated Bob Smith into two different strings while it should be as one field, same with the address. Is there a method I can use to get it in the particular format I want?
P.S Apologies if I explained it vaguely, English isn't my first language.
String z;
try {
BufferedReader br = new BufferedReader(new FileReader("desc.txt"));
z = br.readLine();
} catch(IOException io) {
io.printStackTrace();
}
String[] temp = z.split(" ");
If the format of name and address parts is fixed to consist of two parts, you could just join them:
String z = ""; // z must be initialized
// use try-with-resources to ensure the reader is closed properly
try (BufferedReader br = new BufferedReader(new FileReader("desc.txt"))) {
z = br.readLine();
} catch(IOException io) {
io.printStackTrace();
}
String[] temp = z.split(" ");
String name = String.join(" ", temp[0], temp[1]);
String address = String.join(" ", temp[2], temp[3]);
String hobby = temp[4];
Another option could be to create a format string as a regular expression and use it to parse the input line using named groups (?<group_name>capturing text):
// use named groups to define parts of the line
Pattern format = Pattern.compile("(?<name>\\w+\\s\\w+)\\s(?<address>\\w+\\s\\w+)\\s(?<hobby>\\w+)");
Matcher match = format.matcher(z);
if (match.matches()) {
String name = match.group("name");
String address = match.group("address");
String hobby = match.group("hobby");
System.out.printf("Input line matched: name=%s address=%s hobby=%s%n", name, address, hobby);
} else {
System.out.println("Input line not matching: " + z);
}
I can think of three solutions.
In order from best to worst:
Different delimiter
Enforce the format to always have two names, two address parts and one hobby
Have a dictionary with names and hobbies, check each word to determine which type it is and then group them together as needed.
(The 3rd option is not meant as a serious alternative.)
As others have mentioned, using spaces as both field delimiter and inside fields is problematic. You could use a regex pattern to split the line (paste (\w+ \w+) (\w+ \w+) (.+) in Regex101 for an explanation):
Pattern pattern = Pattern.compile("(\\w+ \\w+) (\\w+ \\w+) (.+)");
Matcher matcher = pattern.matcher("Bob Smith ABC Street Bowling Fishing Rollerblading");
System.out.println("matcher.matches() = " + matcher.matches());
for (int i = 0; i <= matcher.groupCount(); i++) {
System.out.println("matcher.group(" + i + ") = " + matcher.group(i));
}
This would give the following output:
matcher.matches() = true
matcher.group(0) = Bob Smith ABC Street Bowling Fishing Rollerblading
matcher.group(1) = Bob Smith
matcher.group(2) = ABC Street
matcher.group(3) = Bowling Fishing Rollerblading
However this only works for this exact format. If you get a line with three name parts for example:
John B Smith ABC Street Swimming
This will get split into John B as the name, Smith ABC as the address and Street Swimming as hobbies.
So either make 100% sure your input will always match this format or use a different delimiter.
The split() method majorly works on the 2 things:
Delimiter and
The String Object
Sometimes on limit too.
Whatever limit you will provide, the split() method will do its work according to that.
It doesn't understand whether the left substring is a name or not, same as for the right substring.
Have a look at this code snippet:
String assets = "Gold:Stocks:Fixed Income:Commodity:Interest Rates";
String[] splits = assets.split(":");
System.out.println("splits.size: " + splits.length);
for(String asset: splits){
System.out.println(assets);
}
OutPut
splits.size: 5
Gold
Stocks
Fixed Income // with space
Commodity
Interest Rates // with space
The output came with spaces because I provided the ; as a delimiter.
This probably helped you to get your answer.
Find Detailed Information on Split():
Top 5 Use cases of Split()
Java Docs : Split()
It depends on the data you're dealing with. Will the name always consist of a first and last name? Then you can simply combine the first two elements from the resulting array into a new string.
Otherwise, you might have to find a different way to separate out the different pieces within the txt file. Possibly a comma? Some character that you know won't ever be used in your normal data.
Assuming that every line follows the format
Bob Smith ABC Street Swimming
ie, name surname.... this code can manually manipulate the data for you:
String[] temp = z.split(" ");
String[] temp2 = new String[temp.length - 1];
temp2[0] = temp[0] + " " + temp[1];
for (int i = 2; i < temp.length; i++) {
temp2[i] = temp2[i];
}
temp = temp2;

java: splitting one array into two separate arrays based on even and odd positions of the array

I'm new to Java and I'm having difficulties I have an assignment that requires me to load a text file with the name of a state followed by its capital onto the program and read the state names into one array and the capital names into another array. The way I tackled this was that I loaded the text file into one array called total and made a count. I wanted to split those with an even position to be in a separate array called capital and those in an odd position to be in an array called states. But I'm not sure how exactly to put that into code. This is what I have so far
Sample of Text File:
Alabama
Montgomery
Alaska
Juneau
Arizona
Phoenix
Arkansas
Little Rock
California
Sacramento
Colorado
Denver
Connecticut
Hartford
Delaware
Dover
Florida
Tallahassee
Georgia
Atlanta
Hawaii
Honolulu
And my code so far
public class StateCapitals
{
/**
* #param args the command line arguments
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException
{
File inputfile;
File outputfile;
inputfile = new File("capitals.txt");
outputfile = new File ("InOrder.txt");
String stateandcity;
int count;
count = 1;
PrintWriter pw;
Scanner kb;
kb = new Scanner(inputfile);
String [] total;
total = new String[100];
String [] capitals;
capitals = new String[50];
String [] states;
states = new String [50];
while (kb.hasNextLine())
{
stateandcity = kb.nextLine();
System.out.println("Count: " +count + " " + stateandcity);
total[count-1] = stateandcity;
count ++;
}
if (count % 2 == 0)
states = new String [50]; //where i need help
}}
The algorithm will be like this:
Read everything into total like you have already thought of.
Use a for loop to loop from i=0 to i=100 (or however many items there are to be split), incrementing by 2 each time.
Assign total[i] to capital[i / 2].
Assign total[i + 1] to states[i / 2].
It is as simple as that! Try doing it yourself first. If you are having difficulties, just leave a comment!
I would separate them while reading them like this. (Save yourself a loop)
while (kb.hasNextLine())
{
state[count] = kb.nextLine();
capitals[count] = kb.nextLine();
System.out.println("Count: " +count + " " +
state[count] + "," +
capitals[count]);
count ++;
}

How do i parse a string to get specific information using java?

Here are some lines from a file and I'm not sure how to parse it to extract 4 pieces of information.
11::American President, The (1995)::Comedy|Drama|Romance
12::Dracula: Dead and Loving It (1995)::Comedy|Horror
13::Balto (1995)::Animation|Children's
14::Nixon (1995)::Drama
I would like to get the number, title, release date and genre.
Genre has multiple genres so I would like to save each one in a variable as well.
I'm using the .split("::|\\|"); method to parse it but I'm not able to parse out the release date.
Can anyone help me!
The easiest would be matching by regex, something like this
String x = "11::Title (2016)::Category";
Pattern p = Pattern.compile("^([0-9]+)::([a-zA-Z ]+)\\(([0-9]{4})\\)::([a-zA-Z]+)$");
Matcher m = p.matcher(x);
if (m.find()) {
System.out.println("Number: " + m.group(1) + " Title: " + m.group(2) + " Year: " + m.group(3) + " Categories: " + m.group(4));
}
(please don't nail me on the exact syntax, just out of my head)
Then first capture will be the number, the second will be the name, the third is the year and the fourth is the set of categories, which you may then split by '|'.
You may need to adjust the valid characters for title and categories, but you should get the idea.
If you have multiple lines, split them into an ArrayList first and treat each one separately in a loop.
Try this
String[] s = {
"11::American President, The (1995)::Comedy|Drama|Romance",
"12::Dracula: Dead and Loving It (1995)::Comedy|Horror",
"13::Balto (1995)::Animation|Children's",
"14::Nixon (1995)::Drama",
};
for (String e : s) {
String[] infos = e.split("::|\\s*\\(|\\)::");
String number = infos[0];
String title = infos[1];
String releaseDate = infos[2];
String[] genres = infos[3].split("\\|");
System.out.printf("number=%s title=%s releaseDate=%s genres=%s%n",
number, title, releaseDate, Arrays.toString(genres));
}
output
number=11 title=American President, The releaseDate=1995 genres=[Comedy, Drama, Romance]
number=12 title=Dracula: Dead and Loving It releaseDate=1995 genres=[Comedy, Horror]
number=13 title=Balto releaseDate=1995 genres=[Animation, Children's]
number=14 title=Nixon releaseDate=1995 genres=[Drama]

How to store stringbuffer into string array?

Hi i am reading sqlite db data and store into string buffer. I want to display it in the list view in android. i am facing little problem. please help me to solve this issue.
String studentno=cursor.getString(1);
String date=cursor.getString(2);
buffer.append("student: "+studentno+" Time:"+date+"\n");
String data=buffer.toString();
Log.d("student: "+studentno+" Time:"+date);
the output is:student: 1234 Time:12:13
student: 1234 Time:12:14
student: 1234 Time:12:15
I want to store string buffer like this
values[0]=student: 1234 Time:12:13
values[1]=student: 1234 Time:12:14
values[2]=student: 1234 Time:12:15
i tried below coding but its not working.
String[] values = data.split("");
for (int i = 0; i < values.length; ++i) {
list.add(values[i]);
}
is there any way to do this. thanks in advance.
You seem to be adding the data into the buffer with new line delimiter at the end. Splitting them should look like this: data.split("\n");
This does not seem like a good idea, however. Mainly because you can have a very large data set and split is an expensive operation.
Why not create an ArrayList<String> and call list.add("student: " + studentno + " Time: " + date) or some other more efficient structure?
Code:
List<String> list = new ArrayList<String>();
String studentno=cursor.getString(1);
String date=cursor.getString(2);
list.add("student: " + studentno + " Time: " + date);
This makes no sense. If you want to store the data in an array, don't store it in a StringBuffer in the first place. Store it directly in the array.
You must have some loop in which you read the data :
String[] arr = new String [...];
int count = 0;
while (cursor.next() && count < arr.length) {
String studentno=cursor.getString(1);
String date=cursor.getString(2);
arr[count] = "student: "+studentno+" Time:"+date+"\n";
count++;
}
You could try to replace your split call with this:
String[] values = data.split("\n");

Java arrays: select and replace values via user inputs

In the program I'm creating, the user will input values to create an array of videos. Each video contains several data fields (number, title, publisher, duration & date). However what I am currently trying to acheive is to let the user choose a particular video in the array they just created, select the data field they wish to rename, rename the value and then set the renamed value as the new value. Here is my code for adding videos to an array:
public Library createLibrary()
{
Library video = new Library();
java.util.Scanner scannerObject =new java.util.Scanner(System.in);
for (int i = 0; i < videos.length; i++)
{
//User enters values into set methods within the Library class
System.out.print("Enter video number: " + (i+1) + "\n");
String number = scannerObject.nextLine();
System.out.print("Enter video title: " + (i+1) + "\n");
String title = scannerObject.nextLine();
System.out.print("Enter video publisher: " + (i+1) + "\n");
String publisher = scannerObject.nextLine();
System.out.print("Enter video duration: " + (i+1) + "\n");
String duration = scannerObject.nextLine();
System.out.print("Enter video date: " + (i+1) + "\n");
String date= scannerObject.nextLine();
System.out.print("VIDEO " + (i+1) + " ENTRY ADDED " + "\n \n");
//Initialize arrays
videos[i] = new Library ();
videos[i].setVideo( number, title, publisher, duration, date );
}
return video;
}
And here is the basic concept for my select and replace function for those who can't figure out what I mean:
public void replaceVideo(Library[] videos, String replaceTo, String replaceWith)
{
for (int i = 0; i < videos.length; i++)
if (videos[i].equals(replaceTo)) {
videos[i]= replaceWith;
}
}
Simpler solutions will be appreciated. Thanks.
Try comparing replaceTo to the name of the video (or whatever replaceTo is supposed to match):
if (videos[i].getName().equals(replaceTo)) {
I can't see your replace ever working, since it appears that you are comparing a Library type and a String type with .equals().
If you use one of the Collection classes instead of an array, the replace method changes to
public void replaceVideo(Vector<Library> videos, Library current, Library newCopy)
{
Collections.replaceAll(videos, current, newCopy);
}
I used Vector, but you could use a Set, List, etc. as needed.
For your code to work, you need to override the Library.equals method to compare strings only. Otherwise, you can compare the video title, for one sample, against the parameter replaceTo.
Certainly, it is OOP elegant to override the equals method. Try my suggestion and Thomas'
Good luck.

Categories

Resources