Create and populate HashMap<Integer, ArrayList<object>> - java

I have an assignment for school that's all about using files, HashMap and ArrayList. This assignment requires 4 classes.
The first class is called FileReader and reads a txt file which is written line by line and each field that we need is separated by ";", for example ("Columbia University";"USA";78.86;2012). Each line contains 2 strings (university name and country) and 2 numbers (score and year). The FileReader class after reading the txt file returns its content in an arraylist.
The second class of the assignment is called UniversityScores and it has 4 fields (uniname, country, score, year), a constructor, accessor methods for all fields and a toString method.
The third class is the heart of our program. This class is called FileEditor and creates a Hashmap<Integer,ArrayList<UniversityScores>> where the key is the year field of each object and value I guess is the rest of the line. My problem is filling the right way the HashMap.
Also, my final 4th class is called FileWriter which creates a new txt and writes inside of it. All my classes work as supposed to except my FileEditor class. Any help needed. Thank you in advance!
Edit
I am supposed to write some other methods as well. For now my problem is the FileEditor class. I also posted the TestFiles class which contains the main function.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
class FileReader{
private String fileName;
private Scanner scanner;
private File file;
private ArrayList<String> arrayList;
private String line;
public FileReader(String otherFileName){
this.fileName = otherFileName;
this.file = new File(fileName);
}
public boolean initReader(){
try {
scanner = new Scanner(file);
}
catch (FileNotFoundException e) {
System.out.println("Just caught a FileNotFoundException.");
}
if(file.exists()){
return true;
}
else{
return false;
}
}
public ArrayList<String> readFile(){
this.arrayList = new ArrayList<String>();
while (scanner.hasNextLine()) {
this.line = scanner.nextLine();
arrayList.add(line);
}
arrayList.remove(0);
//System.out.println(arrayList);
return arrayList;
}
public void closeReader(){
scanner.close();
System.out.println("Scanner closed");
}
}
‌
import java.util.ArrayList;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class FileWriter{
private String path;
private PrintWriter writer;
private File outputFile;
public FileWriter(String otherPath){
this.path = otherPath;
this.outputFile = new File(path);
}
public boolean initWriter(){
try{
writer = new PrintWriter(path);
}
catch (FileNotFoundException e){
System.out.println("just caught an exception");
}
if(outputFile.exists()){
return true;
}
else{
return false;
}
}
public void writeFile(){
writer.println("The first line");
writer.println("The second line");
writer.println("Christos");
}
public void closeWriter(){
writer.close();
System.out.println("Writer closed");
}
}
‌
class UniversityScore{
private String name;
private String country;
private double score;
private int year;
public UniversityScore(String otherName, String otherCountry, double otherScore, int otherYear){
this.name = otherName;
this.country = otherCountry;
this.score = otherScore;
this.year = otherYear;
}
public String getName(){
return name;
}
public String getCountry(){
return country;
}
public double getScore(){
return score;
}
public int getYear(){
return year;
}
public String toString(){
String outputString = name + "\t" + country + "\t" + score + "\t" + year;
return outputString;
}
}
‌
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
class FileEditor{
private HashMap<Integer, ArrayList<UniversityScore>> scores = new HashMap<Integer, ArrayList<UniversityScore>>();
private ArrayList<String> lines;
public FileEditor(ArrayList<String> otherLines){
this.lines = otherLines;
}
public void fillHashMap(){
// that's where I need help
}
}
public class TestFiles {
public static void main(String[] args){
FileReader reader = new FileReader("universities.txt");
if(reader.initReader()){
FileEditor editor = new FileEditor(reader.readFile());
reader.closeReader();
editor.fillHashMap();
FileWriter writer = new FileWriter("universities_2015_output.txt");
if(writer.initWriter()){
writer.writeFile(editor.getScoresOfYear(2015));
writer.closeWriter();
}
else{
System.out.println("Error creating file");
}
System.out.println("Average university score of year 2015: "+editor.getAverageOfYear(2015));
System.out.println("Min university score of year 2015: "+editor.getMinOfYear(2015));
System.out.println("Max university score of year 2015: "+editor.getMaxOfYear(2015));
}
else{
System.out.println("Error opening file");
}
}
}

You will need a way to parse your lines into UniversityScore objects.
Now that you have all the scores, you can add it to your map, according to their year values (may be score but the type doesn't match nor makes practical sense), for example:
for(String line : lines){
String[] vals = line.split(";");
UniversityScore score = new UniversityScore(vals[0],vals[1],Double.parseDouble(vals[2]),Integer.parseInt(vals[3]))
if(scores.containsKey(score.getYear()){ // If the key exists
scores.get(score.getYear()).add(score);
}else{ // If the key doesn't exist, it must be created and added to the map
ArrayList<UniversityScore> newList = new ArrayList<>();
newList.add(score);
scores.put(score.getYear(), newList)
}
}
I noticed your map has an Integer key which corresponds to the year property of a score, so I assumed the map's keys are the years and not the scores as you suggested.
I didn't check if the code works, but it should at least give you an idea on how to fill your map.

It looks like you're being tasked with reading data from a file, and then generating some stats about the data in the file.
Currently, you're simply plopping each line in the ArrayList.
Looks like your next step is to go through each item in that list, and create a UniversityScore object. This is where you will have to parse each string into values that can be assigned to the various fields in the UniversityScore object. When you have done that, put the current line number (as an Integer key) and UniversityScore (as the value) in your HashMap.
Once you have done that, you will have to write the missing methods getScoresOfYear(Integer year), getAverageOfYear(int year), getMinOfYear(int year), and getMaxOfYear(int year) in the editor class.

try this:
public void fillHashMap() {
for(String line : lines) {
String [] fields = line.split(";");
UniversityScores us = new UniversityScores(fields[0], fields[1], fields[2], fields[3]);
if (scores.keySet().contains(us.getScore())) {
scores.get(us.getScore()).add(us);
}
else {
ArrayList<UniversityScores> t = new ArrayList<UniversityScores>();
t.add(us);
scores.put(us.getScore(), t);
}
}
}

Related

How can I use Java to create a list of all the values from csv file that have the same row name

Excel file I'm using
I want to parse a csv file and extract the name, like 'chair' and then a list of each possible colour, so ['Blue','Green','Yellow']. How can I do this?
I have created a class Object, that has a 'String name' and a 'Listcolours'.
CSVReader reader = new CSVReader(new FileReader(new File(url.toURI()).getAbsolutePath()));
Object<API> listings = new ArrayList<Object>();
String [] line;
List<String> colourList = new ArrayList<>();
reader.readNext();
while ((line = reader.readNext()) != null) {
String name = line[0];
String colour = line[1];
colourList.add(operation);
Object object = new Object(name,colourList);
listings.add(object);
}
You can create a Hashmap with key as name of the item and value as list of colors available.
I hope below snippet will solve your problem. Good Luck!!
HashMap<String,List<String>> data = new HashMap<>();
String [] line;
reader.readNext();
while ((line = reader.readNext()) != null) {
String name = line[0];
String colour = line[1];
if(data.containsKey(name.toLowerCase())){
data.get(name.toLowerCase()).add(colour.toLowerCase());
}
else{
List<String> colorList = new ArrayList<>();
colorList.add(colour.toLowerCase());
data.put(name.toLowerCase(),colorList);
}
}
#g00se what do you mean by a 'stream grouping operation'
I'll show you. Actually, in your case, since you're using a proper csv API, you can leverage that to create beans first, then do the grouping. Here's what I mean by stream grouping: we create a Map<String, HouseholdObject>> (yes that's my name for your entities - pity it's got the word 'object' in it, but never mind). That collects them into groups having the same name:
package com.technojeeves.opencsvbeans;
import com.opencsv.bean.CsvToBeanBuilder;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class HouseholdParser {
public static void main(String[] args) {
try {
List<HouseholdObject> objects = new HouseholdParser().read(new File(args[0]));
Map<String, List<HouseholdObject>> objectsGroupedByName =
objects.stream()
.skip(1)
.collect(groupingBy(HouseholdObject::getName));
System.out.println("The following groups of household objects were found:");
objectsGroupedByName.entrySet()
.stream()
.forEach(e -> {
System.out.println(e.getKey());
e.getValue()
.stream()
.forEach(v -> System.out.printf("\t%s%n", v.getColour()));
});
} catch (Throwable t) {
t.printStackTrace();
}
}
public List<HouseholdObject> read(File file) {
try (FileReader reader = new FileReader(file)) {
return new CsvToBeanBuilder(reader).withType(HouseholdObject.class).build().parse();
} catch (IOException e) {
throw new RuntimeException("Cannot read file: " + file.getName() + e);
}
}
}
Here's the bean I made for it:
package com.technojeeves.opencsvbeans;
import com.opencsv.bean.CsvBindByPosition;
import com.opencsv.bean.CsvCustomBindByPosition;
import com.opencsv.bean.AbstractBeanField;
import com.opencsv.bean.CsvRecurse;
public class HouseholdObject {
#CsvBindByPosition(position = 0)
private String name;
#CsvBindByPosition(position = 1)
private String colour;
public HouseholdObject() {
}
public HouseholdObject(String name, String colour) {
this.name = name;
this.colour = colour;
}
public String getName() {
return this.name;
}
public String getColour() {
return this.colour;
}
public void setName(String name) {
this.name = name;
}
public void setColour(String colour) {
this.colour = colour;
}
#Override
public String toString() {
return String.format("%s=%s,%s=%s", "name", name, "colour", colour);
}
#Override
public boolean equals(Object o) {
HouseholdObject other = (HouseholdObject)o;
return name.equals(other.name) && colour.equals(other.colour);
}
#Override
public int hashCode() {
return name.hashCode() * colour.hashCode();
}
}
And here's my output with your source CSV:
The following groups of household objects were found:
Table
Purple
Pink
Chair
Blue
Green
Yellow
Door
Yellow

How to Store Variable Data back from file in Java

Problem Defined: I store bookname and bookauthor variable data in file using tostring to buffer writer, When i run program next time program read the file but not to store data back to the variable
Please write read code and and variable data storing from file in JAVA
...........................................................................................................................................................
Three Classes One is Main Class,Second is filewriting class and One Class having book add function.Source Code is given here
import java.util.Scanner;
import java.io.*;
public class AddBook extends Filewriting{
public int add;
public AddBook(int add){this.add=add;}
public String bookname[] = new String[15];
public String bookauthor[] = new String[15];
public int price[] = new int[15];
public void addbook(){
for(int i=0;i<add;i++){
System.out.println("Enter the Book Title:");
Scanner input=new Scanner(System.in);
bookname[i]=input.nextLine();
System.out.println("Enter the Book Author:");
Scanner scan=new Scanner(System.in);
bookauthor[i]=input.nextLine();
System.out.println("Enter the Book Price:");
Scanner input1=new Scanner(System.in);
price[i]=input1.nextInt();
}
}
public String toString(int j)
{
return String.format("BookName:%s%nBookAuthor:%s%nBookPrice:%d%n%n................................................................................................................................%n",bookname[j],bookauthor[j],price[j]);
}
}
import java.util.*;
import java.io.*;
public class Filewriting {
public int add;
public void filewriting(){
System.out.println("How many Books you want to added:");
Scanner in=new Scanner(System.in);
add=in.nextInt();
try{
File file = new File("Hello1.txt");
// creates New file
file.createNewFile();
Writer writer = new FileWriter("Hello1.txt",true);
BufferedWriter bufferWriter = new BufferedWriter(writer);
AddBook obj=new AddBook(add);
obj.addbook();
for ( int i = 0; i < add; i++){
// bufferWriter.write(obj.bookname[i] + obj.bookauthor[i] +obj.price[i]);
bufferWriter.write(obj.toString(i));
}
bufferWriter.close();
}
catch(Exception e)
{
}
}
/* // Creates a FileReader Object
FileReader fr = new FileReader(file);
char [] a = new char[50];
fr.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); // prints the characters one by one
fr.close(); */
}
import java.util.Scanner;
import java.io.*;
public class Test{
public static void main(String args[]){
System.out.println("Enter 1 to Add Books:");
System.out.println("Enter 2 to Check Store Books again in Variable:");
Scanner input=new Scanner(System.in);
int i=input.nextInt();
if(i==1){
System.out.println("You Press B");
Filewriting fw=new Filewriting();
fw.filewriting();
}
if(i==2)
{
Filewriting fw=new Filewriting();
AddBook obj=new AddBook(fw.add);
for ( int j = 0; j < 2; j++) // for storing 2 variables data
{
System.out.println(obj.bookname[j]); // just check bookname,shows null
}
}
// Please write code that we read the file as well as data is stored again in Variables
}
}
I see You can write Data in File as not well.From your Code it is impossible to Store data in your variables.You must set and get Methods in your program in order to store variables.Following Program Code is help you to storing file data to variable perfectly.
................................................................................
public class Book {
public String name;
public String author;
public int price;
public Book(){
this("","",0);
}
public Book(String name,String author,int price){
setName(name);
setAuthor(author);
setPrice(price);
}
public void setName(String name){
this.name= name ;
}
public void setAuthor(String author){
this.author = author ;
}
public void setPrice(int price){
this.price = price ;
}
public String getName(){
return name;
}
public String getAuthor(){
return author;
}
public int getPrice(){
return price;
}
}
import java.io.*;
import java.util.*;
public class ReadText {
Scanner input,a;
public void OpenBook(){
File f = new File("Hello1.txt");
if ( f.exists()){
System.out.println("Welcome Ur File IS Open....."+f);
}
else
{
System.out.println("Error... File DOes not exits");
System.exit(1);
}
try {
input = new Scanner(new File("Hello1.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void ReadBook(){
Book b = new Book();
while((input.hasNext())){
b.setName(input.nextLine());
b.setAuthor(input.nextLine());
b.setPrice(Integer.parseInt(input.nextLine()));
System.out.printf("Book Name:%s\nBook Author:%s\nBook Price:%d\n",b.getName(),b.getAuthor(),b.getPrice());
}
}
}

CSV to tab delimited java in command line

Updated Code. This program should take the CSV file and separate it into TSV files by school,but I am not getting it to work. I am getting it to create the files correctly, but only one has any data in it...
public class Student implements Comparable<Student>{
public int id = 0;
public String name = "";
public String school = "";
public Student(int id, String name, String school){
this.id = id;
this.name = name;
this.school = school;
}
public String toString(){
return id+"\t"+name+"\t"+school;
}
#Override
public int compareTo(Student o) {
return this.school.compareTo(o.school);
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class ReadCSV {
public static String CSV_FILE_PATH = "/Users/eringray/Desktop/csvtotab/input.csv";
public static void main(String[] args){
try {
BufferedReader br = new BufferedReader(new FileReader(CSV_FILE_PATH));
BufferedWriter bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + ".tsv"));
ArrayList<Student> list = new ArrayList<Student>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split(",");
if(values.length == 3) {
String idAsString = values[0];
String name = values[1];
String school = values[2];
int id = Integer.parseInt(idAsString);
Student s = new Student(id, name, school);
list.add(s);
}
}
Collections.sort(list);
String currentSchool = "";
for(int i = 0; i < list.size(); i++){
Student stu = list.get(i);
if(currentSchool != stu.school){
currentSchool = stu.school;
bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + stu.school + ".tsv"));
}
String lineText = stu.toString();
bw.write(lineText);
bw.newLine();
}
br.close();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The first thing, you have to do is reading the input file.
I think, you need to read it line by line (depends on file structure).
https://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html
Next step is to seperate the data and sort it by school (if i understood your question well).
For this you have to split the data and create a class to store the information:
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
public Class Student{
public String name = "";
....
public Student(String name, String school, ...){}
}
When you have created a Student object for each student in the list, you have to sort the students by school:
You could implement compareable and use Collection.sort().
https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
Last thing is to print the output, for this you have to override the toString method of the student class:
public String toString(){
return this.id+"\t"+this.name+"\t"+this.school;
}
and iterate throug the list of your students and call the toString method:
System.out.println(students.get(i).toString());
EDIT:
If you need the output in a file and not in the console, just use a fileoutputStream and a bufferedwriter to print the output of the toString method in a file.

Reading integers in .txt file and store in arraylist

I know this question might be answered many times. However, I still cannot solve this specific problem.
Basically I have a .txt file with the following format.
String Integer String
For example,
la 789 ferrari
turbo 560 porsche
veyron 987 bugatti
sls 563 benz
dbs 510 aston
How can I read the file line by line and store the numbers/integers ONLY into arraylist?
Thank you!
Here's a more full Java-esque solution, using Java 7 ... for fun.
Main.java
import java.util.List;
public class Main
{
private static final InputFileParser inputFileParser = new InputFileParser();
private static final EntryNumberExtractor extractor = new EntryNumberExtractor();
private static final String FILENAME = "input-file.txt";
public static void main(String... args)
{
List<Entry> entries = inputFileParser.parse(FILENAME);
List<Integer> extractedIntegers = extractor.extract(entries);
System.out.println("Entries: ");
prettyPrintListItems(entries);
System.out.println();
System.out.println("Entry numbers: ");
prettyPrintListItems(extractedIntegers);
}
private static <T> void prettyPrintListItems(List<T> list)
{
for (T item : list)
{
System.out.println(item);
}
}
}
InputFileParser.java
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class InputFileParser
{
public List<Entry> parse(String filename)
{
List<Entry> entries = new ArrayList<>();
File f = new File(filename);
try (BufferedReader reader = new BufferedReader(new FileReader(f));)
{
String line = null;
while ((line = reader.readLine()) != null)
{
String[] components = line.split(" ");
entries.add(new Entry(components[0], Integer.parseInt(components[1]), components[2]));
}
}
catch (IOException e)
{
e.printStackTrace();
}
return entries;
}
}
EntryNumberExtractor.java
import java.util.ArrayList;
import java.util.List;
public class EntryNumberExtractor
{
public List<Integer> extract(List<Entry> entries)
{
List<Integer> integers = new ArrayList<>();
for (Entry e : entries)
{
integers.add(e.getNumber());
}
return integers;
}
}
Entry.java
public class Entry
{
private String model;
private int number;
private String company;
public Entry(String model, int number, String company)
{
this.model = model;
this.number = number;
this.company = company;
}
public Integer getNumber()
{
return number;
}
#Override
public String toString()
{
return "model: " + model + ", number: " + number + ", company: " + company;
}
}
ArrayList<int> list = new ArrayList<int>();
try {
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
String line = br.readLine();
while(line != null)
{
String[] tokens = line.Split(" ");
list.Add(Integer.parseInt(tokens[1]));
line = br.readLine()
}
catch(Exception e)
{
//Probably a conversation exception or a index out of bounds exception
}
You can read each line and split the line string by space, retrieve the number and store it in array list

File always seems to be empty

Ok, I'm really confused by some code I wrote. It's a DataSetter (didn't know a better name for it...), and has methods to change the data in my data file (data.txt). This data has the following format: #key=value (eg. #version=1.0). Now, I tried to run this line of code:
new DataSetter().setValue("version", "1.1");
It just clears the file. That's pretty much all it does. Now, I think it clears the file because it makes a new File, which is completely empty but has the same name. Here's my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
/**
* This class contains methods to set specific data in the data.txt file. <br>
* The data is rewritten every time a new value is set.
*
* #author Casper van Battum
*
*/
public class DataSetter {
private static final File DATA_FILE = new File("resources/data.txt");
private static final String lineFormat = "#%s=%s";
private FileOutputStream out;
private DataReader reader = new DataReader();
private HashMap<String, String> dataMap = reader.getDataMap();
private Scanner scanner;
public DataSetter() {
try {
out = new FileOutputStream(DATA_FILE, false);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void setValue(String key, String newValue) {
openDataFile();
String oldLine = String.format(lineFormat, key, dataMap.get(key));
dataMap.put(key, newValue);
String newLine = String.format(lineFormat, key, newValue);
try {
replace(oldLine, newLine);
} catch (IOException e) {
e.printStackTrace();
}
closeDataFile();
}
private void replace(String oldLine, String newLine) throws IOException {
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine();
tmpData.add((currentLine == oldLine) ? newLine : currentLine);
}
out.write(new String().getBytes());
String sep = System.getProperty("line.separator");
StringBuffer sb = new StringBuffer();
for (String string : tmpData) {
sb.append(string + sep);
}
FileWriter writer = new FileWriter(DATA_FILE);
String outString = sb.toString();
writer.write(outString);
writer.close();
}
private void openDataFile() {
try {
scanner = new Scanner(DATA_FILE);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
private void closeDataFile() {
scanner.close();
}
}
So after running the setValue() method, I just have an empty file...
Im really out of idea's on how to solve this...
You are truncating your data file with the
new FileOutputStream(DATA_FILE, false)
so no nothing is written when you go to output your the elements in the tmpData ArrayList read from Scanner.
ArrayList<String> tmpData = new ArrayList<String>();
while (scanner.hasNextLine()) {
String currentLine = scanner.nextLine(); // never gets called
...
}
The typical strategy for updating a text file is to create a temporary file with old file's contents (File#renameTo), write the data to file, then delete the temporary file after closing any open streams to the file being read.

Categories