Group map elements and sum their values in Java [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I read the below data from a CSV file.
Pedro|groceries|apple|1.42
Nitin|tobacco|cigarettes|15.00
Susie|groceries|cereal|5.50
Susie|groceries|milk|4.75
Susie|tobacco|cigarettes|15.00
Susie|fuel|gasoline|44.90
Pedro|fuel|propane|9.60
I wanted to group the expenses of each customer like
Expense of Pedro:
Groceries - 1.42
fuel - 9.62
I also wanted to group the sum of the expense for each customer like
Total expense for each customer is:
Pedro - (1.42 + 9.60)
Nitin - 15.00
Susie - (5.50 + 4.75 + 15.00 + 44.90)
Can someone help me in how will I group the elements and sum their values.
I am able to read the file and print separate values. I mapped each group member with their expenses. But don't know how to sum up their values
can Someone help me?
This is my code, im sure this is incorrect
static String[] inputArray ;
public static void main(String[] args) throws IOException {
groceryReport gr = new groceryReport();
try {
gr.readFile();
System.out.println(gr.customerPurchase(inputArray).toString());
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#SuppressWarnings("null")
private void readFile() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\....\\grocery.csv"));
String input= "";
try{
System.out.println("The total revenue for each customer is:");
while((input = br.readLine()) != null )
{
inputArray= input.split("\\|");
}
}
catch(Exception e){
e.printStackTrace();
}
finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String customerPurchase(String[] inputArray){
String sum = "" ; float sum1=0; float sum2 = 0;
ArrayList<String[]> alist = new ArrayList<String[]>();
alist.add(inputArray);
String value = "";
System.out.println(alist);
Map<String, String> map = new HashMap<String, String>();
map.put(inputArray[0], inputArray[3]);
System.out.println(map.get(inputArray));
Iterator ite = map.entrySet().iterator();
while (ite.equals("Susie"))
ite.next();
value = map.get("Susie");
sum = sum+ value;
return sum;
}

My solution can be found here, but I will give you a short breakdown of it.
First of all I created a class names Purchase as an abstraction for each of the lines in your csv file. This is just a simple class to group together the information around a purchase (item type, specific item and price).
The createReport method takes the csv lines as input, and will return a datastructure a Map<String, List<Purchase>, the key to the map is going to be the names of the persons, and their associated purchases. If I wanted to fetch all purchases made by Pedro I would simply use mapVariable.get("Pedro"); and it would return a List<Purchases> of all Pedro's purchases.
Finding the sum of Pedro's purchases is therefore a simple task, as can be seen in the sum method.
This ends up giving a report looking like this:
---------------------------------------
Name. Nitin
---------------------------------------
tobacco 15.0
---------------------------------------
Total: 15.0
---------------------------------------
---------------------------------------
Name. Pedro
---------------------------------------
groceries 1.42
fuel 9.6
---------------------------------------
Total: 11.02
---------------------------------------
---------------------------------------
Name. Susie
---------------------------------------
groceries 5.5
groceries 4.75
tobacco 15.0
fuel 44.9
---------------------------------------
Total: 70.15
---------------------------------------

In object oriented languages, when you want to group specific pieces of data, this is accomplished by using classes.
Im assuming this is a homework assignment and so I can't give full details. But you want a person class that contains fields for the info you want. From there you can iimplemet methods to output exactly what you want?

Related

Difficulty with java program passing the txt file into an array list to setup the rest of my program

In the student sample for this book you will find a text file named 1994 weekly gas averages.txt. The file contains 52 lines of text that represent average weekly gas. Line one contains average price for week one and line 2 contains the average price for week 2 etc.
Write a program that reads the gas prices from the file into an array of an ArrayList. The program should do the following.
Display the lowest average price of the year, along with the week number for that price, and the
name of the month which it occurred.
Display the highest average price of the year, along with the week number for that price, and the
name of the month which it occurred.
Display the average gas price for each month.
Txt file gas averages. I'm just starting out with java. Whatever answer is provided, could you keep it simple enough for me to understand since I’m having difficulty.
Part of my code
0.992
0.995
1.001
0.999
1.005
1.007
1.016
1.009
1.004
1.007
1.005
1.007
1.012
1.011
1.028
1.033
1.037
1.04
1.045
1.046
1.05
0.856
1.065
1.073
1.079
1.095
1.097
1.103
1.109
1.114
1.13
1.157
1.161
1.165
1.161
1.156
1.15
1.14
1.129
1.12
1.114
1.106
1.107
1.171
1.123
1.122
1.113
1.117
1.127
1.131
1.134
1.125
You could use this code for reading from file and calculating the lowest price:
public class Test {
public static void main(String[] args) {
List<String> averages = getAllLinesFromFileFromPath("/averages.txt");
double lowest = Double.valueOf(averages.get(0));
for (String line: averages) {
Double weekValue = Double.valueOf(line);
if (lowest>weelValue) {lowest = weekValue;}
}
}
public static List<String> getAllLinesFromFileFromPath(String filename) {
try {
BufferedReader br = new BufferedReader(new FileReader(Paths.get(filename).toFile()));
List<String> result = new ArrayList<>();
String line;
while ((line = br.readLine())!=null) {
result.add(line);
}
br.close();
return result;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

Reverse Names Given [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm looking to reverse the names found in a list given to me (EDIT: given to me from a web scraping of a website) Again not homework
Small sample of list:
Baynes, Aron
Bazemore, Kent
Beal, Bradley
Beasley, Malik
Beasley, Michael
Belinelli, Marco
Bell, Jordan
Bembry, DeAndre'
I need them as Aron Baynes (or Aron,Baynes)
Weirdly people think this is homework problem. THIS IS NOT. I am using NBA player names in a program I have written. I can not post code as the code used is 1000s of lines long. I simply need the ability to reverse the name order in a quick manner compared to my attempts
What I tried: for loops using , as a index then working back and forth using substrings. This did not work well for a list of strings as given above
If you have all names in file (e.g. names.txt):
Baynes, Aron
Bazemore, Kent
Beal, Bradley
Beasley, Malik
Beasley, Michael
Belinelli, Marco
Bell, Jordan
Bembry, DeAndre'
You can:
Read line
split line (using separator)
display in reverse way
import java.io.BufferedReader;
import java.io.FileReader;
public class Main {
public static void main(String[] args) {
// File name
String fileName = "names.txt";
String separator = ", ";
String line;
try (FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
while ((line = bufferedReader.readLine()) != null) {
String[] elements = line.split(separator);
if (elements.length == 2) {
System.out.printf("%s %s\n", elements[1], elements[0]);
} else {
System.out.println("Wrong line: " + line);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Or using List instead of files:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList(
"Baynes, Aron",
"Bazemore, Kent",
"Beal, Bradley",
"Beasley, Malik",
"Beasley, Michael",
"Belinelli, Marco",
"Bell, Jordan",
"Bembry, DeAndre'"
));
String separator = ", ";
// Using loop
for (String person : list) {
String[] elements = person.split(separator);
if (elements.length == 2) {
System.out.printf("%s %s\n", elements[1], elements[0]);
} else {
System.out.println("Wrong line: " + person);
}
}
// Using stream
list.forEach(person -> {
String[] elements = person.split(separator);
if (elements.length == 2) {
System.out.printf("%s %s\n", elements[1], elements[0]);
} else {
System.out.println("Wrong line: " + person);
}
});
}
}

JAVA Array Index Problems

I am not experienced wit Arrays and I am getting this error in the debug console:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at com.company.SortTextFile.main(SortTextFile.java:28)
I've been looking in internet for how other people handle this included here in StackOverflow but I can't seem to understand why is it happening. I am trying to have this program get the input from a text file of multiple columns with 20 lines like this:
Eduardo 15 3.9 30000
And then using collection.sort to sort it using its id.
I am aware the arrays are 0-index however I don't know if I would need to specify the array size.
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import static java.lang.Double.*;
public class SortTextFile {
public static void main(String[] args) throws IOException {
// Creating BufferedReader object to read the input text file
BufferedReader reader = new BufferedReader(new FileReader(
"C:\\Users\\miche\\OneDrive\\Documentos\\University\\Algorithms\\Project\\StudentData.txt"));
// Creating ArrayList to hold Student objects
var studentRecords = new ArrayList<Student>();
// Reading Student records one by one
String currentLine = reader.readLine();
while (currentLine != null) {
String[] studentDetail = currentLine.split("\\s+");
String name = studentDetail[0];
int age = Integer.valueOf(studentDetail[1]);
double GPA = valueOf(studentDetail[2]);
int id = Integer.valueOf(studentDetail[3]);
// Creating Student object for every student record and adding it to
// ArrayList
studentRecords.add(new Student(name, age, GPA, id));
currentLine = reader.readLine();
}
// Sorting ArrayList studentRecords based on marks
Collections.sort(studentRecords, new idCompare());
// Creating BufferedWriter object to write into output text file
BufferedWriter writer = new BufferedWriter(new FileWriter(
"C:\\C:\\Users\\miche\\OneDrive\\Documentos\\University\\Algorithms\\Project\\output.txt"));
// Writing every studentRecords into output text file
for (Student student : studentRecords) {
writer.write(student.name);
writer.write(" " + student.age);
writer.write(" " + student.GPA);
writer.write(" " + student.id);
writer.newLine();
}
// Closing the resources
reader.close();
writer.close();
}
}
I made a Student class to compare the IDs.
public class Student extends SortTextFile {
String name;
int id;
int age;
double GPA;
public Student(String name, int id, double age, double GPA) {
this.name = name;
this.id = id;
this.age = (int) age;
this.GPA = GPA;
}
}
//idCompare Class to compare the marks
class idCompare implements Comparator<Student> {
#Override
public int compare(Student s1, Student s2) {
return s2.id - s1.id;}
}
Edit 1:
The text file just follows a format of Name/Age/GPA/ID:
Chipaldo 25 3.5 29000
Eduardo 15 3.9 30000
Ricardo 23 3.8 18000
Anthony 24 3.9 19000
Lombardo 29 2.0 22000
Romina 28 2.1 23000
Alex 25 3.1 13000
Sofia 21 2.2 24000
Vexler 24 2.2 25000
Albert 19 3.2 14000
John 24 3.0 15000
Melchor 14 2.9 16000
Bernardo 21 4.0 17000
Diego 19 2.1 26000
Miguelangel 25 2.0 27000
Edit 3: I managed to printout the Output in a new file. It sorted it based on age and not ID for some reason. Thank you for your help. I am going to try implement and Binary Insertion Sort to this program instead of doing Collection.sort Thanks.
If possible please be as detailed as possible with any suggestion. English is not my main language & I am slow at this. Thank you in advance
The message simply means that you have an array that only has 1 element in it and you are trying to access array element 2. This is one of those weird things in computer science (and Java as a language) because we start counting from zero rather than one, i.e. the first element in an array is indexed as studentDetail[0] and the second as studentDetail[1]. This is why you see the rather confusing "Index 1 out of bounds for length 1". The array being returned by currentLine.split(" ") only contains one string, not four, as you are expecting. You need to debug the code to find out why this is happening (from what you've provided this is not possible for someone else to answer).
your array seems to only have one entry. check if there is a problem with your string.split(" ")?
Use currentLine.split("\\s+"); This means that there may be one or more spaces or tabs or newlines between fields.
What you did will work correctly if and only if the fields are separated by one single space.
For debugging purpose print the length of the array using System.out.println(studentDetail.length);
Try This. Your code you did not closed writer thats why nothing is to in the output file.
public static void main(String[] args) throws IOException {
//Creating BufferedReader object to read the input text file
BufferedReader reader = new BufferedReader(new FileReader("E:\\Projects\\JavaBasics\\src\\data.txt"));
//Creating ArrayList to hold Student objects
var studentRecords = new ArrayList<Student>();
//Reading Student records one by one
String currentLine = null;
while ((currentLine = reader.readLine()) != null) {
if (!currentLine.isEmpty()) {
System.out.println(currentLine);
String[] studentDetail = currentLine.split(" ");
String name = studentDetail[0];
int age = Integer.valueOf(studentDetail[1]);
double GPA = Double.valueOf(studentDetail[2]);
int id = Integer.valueOf(studentDetail[3]);
studentRecords.add(new Student(name, age, GPA, id));
}
}
//Sorting ArrayList studentRecords based on marks
Collections.sort(studentRecords, new IdCompare());
//Creating BufferedWriter object to write into output text file
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(new File("E:\\Projects\\JavaBasics\\src\\dataout.txt")));
//Writing every studentRecords into output text file
for (Student student : studentRecords) {
System.out.println("Sorted :: " + student.name);
writer.write(student.name);
writer.write(" " + student.age);
writer.write(" " + student.GPA);
writer.write(" " + student.id);
writer.newLine();
}
} finally {
writer.close();
}
}

How do I parse a text file to write certain lines in another text file using java?

I am learning how to work with files in Java. I have a sample file which contains key pairs and it values. I am trying to find a key pairs and if it matches, then output file would be updated with both, key pair and it's value. I am able to get key pairs in output file but unable to get values too. Stringbuilder may work here to append strings but I don't know how.
Below are my input and output files.
Input File:
born time 9 AM London -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: unknown
born time 9 AM Europe -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: december
Expected Output File:
kingNumber 1234567890 birthmonth unknown
kingNumber 1234567890 birthmonth unkbown
Current Output File:
kingNumber birthmonth
kingNumber birthmonth
I am able to write key pair ("kingNumber" and "birthmonth" in this case) to output file but I am not sure what I can do to get it's value too.
String kn = "kingNumber:";
String bd = "birthmonth:";
try {
File f = new File("sample.txt");
Scanner sc = new Scanner(f);
FileWriter fw = new FileWriter("output.txt");
while(sc.hasNextLine()) {
String lineContains = sc.next();
if(lineContains.contains(kn)) {
fw.write(kn + "\n");
// This is where I am stuck. What
// can I do to get it's value (number in this case).
}
else if(lineContains.contains(bd)) {
fw.write(bd);
// This is where I am stuck. What
// can I do to get it's value (birthday in this case).
}
}
} catch (IOException e) {
e.printStackTrace();
}
you could use java.util.regex.Pattern & java.util.regex.Matcherwith a pattern alike:
^born\stime\s([a-zA-Z0-9\s]*)\s--\skingNumber\s(\d+)\s--\saddress:\s([a-zA-Z0-9\s/]*)\s--\sbirthmonth:\s([a-zA-Z0-9\s]*)$
write less, do more.
I have written a simple parser that it following data format from your example.
You will need to call it like this:
PairParser parser = new PairParser(lineContains);
then you can get value from the parser by pair keys
How to get value:
parser.getValue("kingNumber")
Note that keys do not have trailing column character.
The parser code is here:
package com.grenader.example;
import java.util.HashMap;
import java.util.Map;
public class PairParser {
private Map<String, String> data = new HashMap<>();
/**
* Constructor, prepare the data
* #param dataString line from the given data file
*/
public PairParser(String dataString) {
if (dataString == null || dataString.isEmpty())
throw new IllegalArgumentException("Data line cannot be empty");
// Spit the input line into array of string blocks based on '--' as a separator
String[] blocks = dataString.split("--");
for (String block : blocks)
{
if (block.startsWith("born time")) // skip this one because it doesn't looks like a key/value pair
continue;
String[] strings = block.split("\\s");
if (strings.length != 3) // has not exactly 3 items (first items is empty), skipping this one as well
continue;
String key = strings[1];
String value = strings[2];
if (key.endsWith(":"))
key = key.substring(0, key.length()-1).trim();
data.put(key.trim(), value.trim());
}
}
/**
* Return value based on key
* #param key
* #return
*/
public String getValue(String key)
{
return data.get(key);
}
/**
* Return number of key/value pairs
* #return
*/
public int size()
{
return data.size();
}
}
And here is the Unit Test to make sure that the code works
package com.grenader.example;
import com.grenader.example.PairParser;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class PairParserTest {
#Test
public void getValue_Ok() {
PairParser parser = new PairParser("born time 9 AM London -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: unknown");
assertEquals("1234567890", parser.getValue("kingNumber"));
assertEquals("unknown", parser.getValue("birthmonth"));
}
#Test(expected = IllegalArgumentException.class)
public void getValue_Null() {
new PairParser(null);
fail("This test should fail with Exception");
}
#Test(expected = IllegalArgumentException.class)
public void getValue_EmptyLine() {
new PairParser("");
fail("This test should fail with Exception");
}
#Test()
public void getValue_BadData() {
PairParser parser = new PairParser("bad data bad data");
assertEquals(0, parser.size());
}
}

Java, sort and display data from txt file

i'm new with java and have some trouble with one task.
i have txt file which looks like this:
John Doe,01-01-1980,Development,Senior Developer
Susan Smith,07-12-1983,Development,Head of Development
Ane Key,06-06-1989,BA,Junior Analyst
Nina Simone,21-09-1979,BA,Head of BA
Tom Popa,23-02-1982,Development,Developer
Tyrion Lannyster,17-03-1988,BA,Analyst
and i want to to sort it by departments.
for example:
Members are :
[Employee Full Name] - [Employee Age] - [Employee Position] - [Employee Salary(default value x)]
Deparment : Development
Members are :
Susan Smith ......
John Doe ......
Tom Popa ......
Department : BA
Members are :
Nina Simone .......
Ane Key ...........
Tyrion Lannyster ........
at first read file and made 2d array but can't continue how to correctly sort it.
public static void main(String[] args) {
String csvFile = "C:\\Employees.txt";
BufferedReader br = null;
String line = "";
String SplitBy = ",";
String myArray[][] = new String[6][5];
int row = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
String nums[] = line.split(SplitBy);
for (int col = 0; col < nums.length; col++){
String n =nums[col];
myArray[row][col] = n;
// System.out.println(n);
}
row++;
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Providing the code solution here would not help you learn it. But I can give you hints on how to proceed. Using array is not really recommended.
The easy, but dirty way -
Instead of two dimensional array, use a TreeMap<String, String[]> where key is the department concatenated with name and value is the one dimensional array of the individual's details. As we're using TreeMap, the result is naturally sorted based on Department followed by Name of the person. Loop through the entrySet and print all the results.
Right way -
Define new object Person with all the members needed. Implement Comparable interface. Read all the input data, populate the same in Person object, add each such objects in an ArrayList and use Collections API's sort method to sort all the objects. Alternatively you can adapt the Comparator way.
The Java Collections APIallows you to Sort as well as util.Arrays.
You will need the arrays methods for you code, but consider moving to some sort of Collection. Perhaps a List to start with.
The easiest way would put the contents of the lines in Java Beans and then sort them using sort.
public User {
private String name;
// ... all the fields with getters and setters
}
Then adapt your code to something like this:
// create a nice List for the users.
List<User> userList = new ArrayList<>();
while ((line = br.readLine()) != null) {
User user = new User();
String nums[] = line.split(SplitBy);
user.setName(nums[0]);
// create nice method to convert String to Date
user.setDate(convertStringToDate(nums[1]));
// add the user to the list
userList.add(user);
}
// Then finally sort the data according to the desired field.
Arrays.sort(userList, (a,b) -> a.name.compareTo(b.name));

Categories