I am a beginner at Java, and I'm having trouble understanding why I'm getting an error. I have a .csv file containing cities, provinces, and respective populations of Canada. I have been trying to read the file and then put the PROVINCE and POPULATION values into a HashMap (cana) via a key/value pair. I've created a HashSet (canada) to split up the .csv, and I would like to keep that as-is if possible.
My question is about the cana.add(provSet, pop1). I am getting an "cannot find symbol - method add(java.util.Set) error around the "put", and I can't figure out why. Can someone please help me understand what I've done wrong? Since I am a beginner, additional explanation would be greatly appreciated!
String filename = "canada.csv";
try
{
BufferedReader br = new BufferedReader(new FileReader("canada.csv"));
String line = null;
HashSet<String> canada = new HashSet<String>();
HashMap<Set<String>, Set<Integer>> cana = new HashMap<Set<String>, Set<Integer>>();
while((line=br.readLine())!=null) {
String city = line.split(",")[0];
canada.add(city);
String province = line.split(",")[1];
canada.add(province);
Set<String> provSet = new HashSet<String>(Arrays.asList(province));
String population = line.split(",")[2];
canada.add(population);
int p = new Integer(population);
Set<Integer> pop1 = new HashSet<Integer>(Arrays.asList(p));
cana.add(provSet, pop1); //ERROR
//Trying to find the most populated province
String maxProvince = "";
int maxProvPop = 0;
for(String province : cana.keySet()) {
int provPop = cana.get(province);
System.out.println(population);
if( provPop > maxProvPop )
{
maxProvPop = provPop;
maxProvince = province;
}
System.out.println("The most populated province is " + maxProvince + " with a population of " + maxProvPop);
}
I think you're mixing up the methods for HashSet and HashMap. You use the add method for HashSet, and put method for HashMap.
HashSet Documentation
HashMap Documentation
Related
I need to do this for school. Its supposed to be a JAVA project.
So for example, if we give an input:
thomas teacher
charlie student
abe janitor
jenny teacher
The output will be:
teachers,thomas,jenny
students,charlie,
janitor,abe.
I am just a beginner so, so far I have this code:
`Scanner in = new Scanner(System.in);
String line = in.nextLine();
String[] words = line.split(" ");
//TreeMap treemap = new TreeMap();
ArrayList<String> admin = new ArrayList<String>();
Scanner input = new Scanner(System.in);
while(true){
Boolean s = input.nextLine().equals("Done");
//treemap.put(line, "admin");
if(words[1].contentEquals("admin")){
admin.add(words[0]);
}
else if(s == true){
break;
}
}
System.out.println("admins," + "," + admin);`
I was originally using a treemap but I don't know how to make it work so I thought of using an ArrayList and eliminating the brackets at the end.
EDIT:
So I now have the code:
HashMap<String, String> teacher = new HashMap<String, String>();
HashMap<String, String> student = new HashMap<String, String>();
HashMap<String, String> janitor = new HashMap<String, String>();
System.out.println("Enter a name followed by a role.");
Scanner in = new Scanner(System.in);
String line = in.nextLine();
Scanner name = new Scanner(System.in);
String r = name.nextLine();
while(true){
if(line.equals(r + " " + "teacher")){
teacher.put(r, "teacher");
}
}
I'll give you the hint because you should do it yourself.
Use a HashMap<String, List<String>> map and insert your inputs like below:
if(map.containsKey(words[1]))
{
List<String> list = map.get(words[1]);
list.add(words[0]);
map.put(words[1],list);
}
else
{
map.put(words[1],Arrays.asList(words[0]))
}
This way you will get list of names corresponding to each types(student/teacher) etc.
After that iterate over the map and print the list.
I think for a small amount of occupations it's reasonable to accomplish this using just array lists. I think the part you are having trouble with is the input structure so I'll help you out with an example of how to do that part and let you handle the filtering on your own:
private List<String> teachers = new ArrayList<>();
private List<String> students = new ArrayList<>();
private List<String> janitors = new ArrayList<>();
public void seperatePeople(){
Scanner in = new Scanner(System.in);
while(true){
//Keep getting the next line in an infinite loop
String line = in.nextLine();
if(line.equals("Done")){
break; //end the loop
}else{
//Split on the spaces
String[] personArray = line.split(" ");
//Remember each line is structured like : name, occupation
//So when we split the line the array list we get from it
//will be in the same order
putInArray(personArray[0], personArray[1]);
}
}
//Do whatever printing you have to do down here
}
private void putInArray(String name, String occupation) {
//filter and add to the correct list in here
}
If you wanted to implement this using a hashmap the input method would be the same, but instead of putting names into 3 pre-made occupation arraylists you create arraylists and put them inside a hashmap as you go:
private HashMap<String, List<String>> peopleHashMap = new HashMap<>();
public void seperatePeople(){
Scanner in = new Scanner(System.in);
while(true){
//Keep getting the next line in an infinite loop
String line = in.nextLine();
if(line.equals("Done")){
break; //end the loop
}else{
//Split on the spaces
String[] personArray = line.split(" ");
//Remember each line is structured like : name, occupation
//So when we split the line the array list we get from it
//will be in the same order
putInArray(personArray[0], personArray[1]);
}
}
//You can get all the keys that you created like this
List<String> keys = new ArrayList<>(peopleHashMap.keySet());
}
private void putInArray(String name, String occupation) {
if(peopleHashMap.containsKey(occupation)){
//If the key (occupation in this case) is already in the hashmap, that means that we previously
//made a list for that occupation, so we can just the name to that list
//We pull out a reference to the list
List<String> listOfNames = peopleHashMap.get(occupation);
//And then put the new name into that list
listOfNames.add(name);
}else{
//If the key isn't in the hashmap, then we need to make a new
//list for this occupation we haven't seen yet
List<String> listOfNames = new ArrayList<>();
//We then put the name into the new list we made
listOfNames.add(name);
//And then we put that new list with the into the hashmap with the occupation as the key
peopleHashMap.put(occupation, listOfNames);
}
}
I'm currently using Jersey REST to create a webpage that has a list of birds and taxonomy number, with a link to a page specifically about the bird in question. While my links work between the two pages, and my Bird Name and Taxonomy Number appear, I can't get the order or family name to appear. Following is the code in question.
#Path("/birdslist")
public class BirdsList extends Birds {
#GET
#Path("/all")
#Produces("text/html")
public String all() {
Iterator iterator = birdnames.keySet().iterator();
String page = "<html><title>All Birds</title><body>";
page += "<p>This is the list of all birds. <br> Click the taxonomy number of the bird you wish to view in detail.</p>";
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
for (String key : birdnames.keySet()) {
page += String.format("<p>Name:%s <br> Taxonomy Number:<a href=%s>%s</a></p>",birdnames.get(key),key,
key);
getBird(key);
}
page += "</body></html>";
return page;
}
#GET
#Path("{key}")
#Produces("text/html")
public String getBird(#PathParam("key") String key) {
String page = "<html><title>Bird #: {key}</title><body>";
page += String.format("<p>This page contains info on the %s</p>",birdnames.get(key));
page += String.format("<p>Name:%s <br> Taxonomy Number:%s <br> Family:%s <br> Order:%s</p>",birdnames.get(key),key,family.get(key),order.get(key));
page += "<p>Please click <a href=all>here</a> to return to the list of all birds.</p>";
page += "</body></html>";
return page;
}
}
The family and order are saved in a HashSet that is inside of a hashmap, while bird name is in a hashmap. It was written over from a csv file and converted into hashmaps. Following is that code.
public class Birds {
HashMap<String,String> birdnames;
HashMap<String,HashSet<String>> family;
HashMap<String,HashSet<String>> order;
/**
Constructor reads the CSV of all birds
*/
public Birds() {
// long path to eBirds assuming Maven "mvn exec:java" is many levels up
String fileName = "src/main/java/com/example/rest/eBirds.csv";
boolean firstLine = true;
this.birdnames = new HashMap<String,String>();
this.family = new HashMap<String,HashSet<String>>();
this.order = new HashMap<String,HashSet<String>>();
try {
BufferedReader R = new BufferedReader(new FileReader(fileName));
String line;
while (true) {
line = R.readLine();
if (line == null) break;
if (firstLine) { // ignore the first line, it's not a bird
firstLine = false;
continue;
}
String[] fields = line.split(",");
if (!fields[1].equalsIgnoreCase("species")) continue; // ignore all but species records
birdnames.put(fields[0],fields[4]); // add this bird to name table
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername)) { // if needed, create first-time order set
order.put(ordername,new HashSet<String>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
// extract the family name from fields[7] -- removing quotes first if needed
String famname = fields[7].replace("\"","");
if (!family.containsKey(famname)) { // if needed, create first-time family set
family.put(famname,new HashSet<String>());
}
family.get(famname).add(fields[0]); // new family member by number for lookup
}
}
catch (IOException e) { System.out.println("Stack trace: " + e); }
}
...
}
I've never used HashSets before, that was part of the given info to us. Our assignment was to create a list page and pages specific to each bird and link between the two. I just can't get these last two values to appear correctly. Can anyone help?
Here you use the same key for all values, birdnames, family and order:
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
But you initialize them with different keys:
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername))
{ // if needed, create first-time order set
order.put(ordername, new HashSet<>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
Here the key would be fields[6] and not the birdnames key.
If you want to keep using the same key, you could do the following for the orders:
if (!order.containsKey(fields[0]))
{
order.put(fields[0], new HashSet<>());
}
order.get(fields[0]).add(fields[6]);
Then you can use:
HashSet ord = order.get(key);
And you will receive all the orders for that bird name.
If you don't want to change that and still use the same key you could do something like the following, but that is highly discouraged as it destroys the purpose of using a map in the first place:
Set<String> ord = new HashSet<>();
for (String tmp : order.keySet())
{
if (order.get(tmp).contains(key))
ord.add(tmp);
}
Here ord would contain all the orders for the "key".
As you can see, you need to do much more redundant work, if you don't switch value and "key".
Mongodb has an update function, where it can increment pre-existing fields. However, I found that it could only update flat JSON. Whenever there's a JSONObject inside of a JSONObject, with a value I want to increment, I can't actually seem to do it. It will return this error:
com.mongodb.WriteConcernException: Write failed with error code 14 and error message
'Cannot increment with non-numeric argument: {laneQty: { BOTTOM: 1 }}'
As you can see, I tried update incrementing laneQty.BOTTOM by 1. I don't want to write an algorithm to change every single layered json field into dot notation(like laneQty.BOTTOM), so is there a way to either turn the JSON into dot notation pre-upsert?
For now my general upsert function looks like this:
public boolean incrementJson(BasicDBObject json, String colName, ArrayList<String> queryParams, ArrayList<String> removeParams){
/*make sure the game id AND the main player id can't both be the same.
If either/or, it's fine. We don't want duplicates.
*/
BasicDBObject query = new BasicDBObject();
DBCollection collection = db.getCollection(colName);
for(int i = 0; i < queryParams.size(); i++){
String param = queryParams.get(i);
query.put(param, json.get(param));
}
for(String param : removeParams){
json.remove(param);
}
return collection.update(query, new BasicDBObject("$inc", json), true, false).isUpdateOfExisting();
}
Is there any suggested upgrades to this code that could make it easily update layered json as well? Thank you!
By the way, it'll be very hard for me to hardcode this. There are a ton of layered objects and that would take me forever. Also, I am not in complete control of which fields are populated in the layers, so I can't just say laneQty.BOTTOM every single time because it will not always exist. Prior to upserting, the BasicDBObject json was actually a java bean parsed into BasicDBObject. This is its constructor if it's of any help:
public ChampionBean(int rank, int division, int assists, int deaths, int kills, int qty, int championId,
HashMap<String, Integer> laneQty, HashMap<String, Integer> roleQty,
ParticipantTimelineDataBean assistedLaneDeathsPerMinDeltas,
ParticipantTimelineDataBean assistedLaneKillsPerMinDeltas, ParticipantTimelineDataBean creepsPerMinDeltas,
ParticipantTimelineDataBean csDiffPerMinDeltas, ParticipantTimelineDataBean damageTakenDiffPerMinDeltas,
ParticipantTimelineDataBean damageTakenPerMinDeltas, ParticipantTimelineDataBean goldPerMinDeltas,
ParticipantTimelineDataBean xpDiffPerMinDeltas, ParticipantTimelineDataBean xpPerMinDeltas, int wins,
int weekDate, int yearDate) {
super();
this.rank = rank;
this.division = division;
this.assists = assists;
this.deaths = deaths;
this.kills = kills;
this.qty = qty;
this.championId = championId;
this.laneQty = laneQty;
this.roleQty = roleQty;
this.assistedLaneDeathsPerMinDeltas = assistedLaneDeathsPerMinDeltas;
this.assistedLaneKillsPerMinDeltas = assistedLaneKillsPerMinDeltas;
this.creepsPerMinDeltas = creepsPerMinDeltas;
this.csDiffPerMinDeltas = csDiffPerMinDeltas;
this.damageTakenDiffPerMinDeltas = damageTakenDiffPerMinDeltas;
this.damageTakenPerMinDeltas = damageTakenPerMinDeltas;
this.goldPerMinDeltas = goldPerMinDeltas;
this.xpDiffPerMinDeltas = xpDiffPerMinDeltas;
this.xpPerMinDeltas = xpPerMinDeltas;
this.wins = wins;
this.weekDate = weekDate;
this.yearDate = yearDate;
}
The participantTimelineDataBean is another bean with 4 int fields inside of it. I want to increment those fields (so yes it's only 2 layers deep, so if there's a solution with 2 layers deep availability I'll take that too).
Use the dot-notation:
new BasicDBObject("$inc", new BasicDBObject("laneQty.BOTTOM", 1) )
Alternative quick&dirty solution: Just collection.save the whole document under the same _id.
Use this library:
https://github.com/rhalff/dot-object
For example if you have an object like this:
var jsonObject = {
info : {
firstName : 'aamir',
lastName : 'ryu'
email : 'aamiryu#gmail.com'
},
}
then your node.js code would be like this:
var dot = require('dot-object');
var jsonObject = // as above ;-);
var convertJsonObjectToDot = dot.dot(jsonObject);
console.log(convertJsonObjectToDot);
Output will be as shown below:
{
info.firstName : 'aamir',
info.lastName : 'ryu',
info.email : 'aamiryu#gmail.com
}
Please bear with me, this is my first answer on stackoverflow ever, since i was searching for the same thing and i found one solution to it, hope it helps you out.
I am working on a project where I have been given a text file and I have to add up the points for each team and printout the top 5 teams.
The text file looks like this:
FRAMae Berenice MEITE 455.455<br>
CHNKexin ZHANG 454.584<br>
UKRNatalia POPOVA 453.443<br>
GERNathalie WEINZIERL 452.162<br>
RUSEvgeny PLYUSHCHENKO 191.399<br>
CANPatrick CHAN 189.718<br>
CHNHan YAN 185.527<br>
CHNCheng & Hao 271.018<br>
ITAStefania & Ondrej 270.317<br>
USAMarissa & Simon 264.256<br>
GERMaylin & Daniel 260.825<br>
FRAFlorent AMODIO 179.936<br>
GERPeter LIEBERS 179.615<br>
JPNYuzuru HANYU 197.9810<br>
USAJeremy ABBOTT 165.654<br>
UKRYakov GODOROZHA 160.513<br>
GBRMatthew PARR 157.402<br>
ITAPaul Bonifacio PARKINSON 153.941<br>
RUSTatiana & Maxim 283.7910<br>
CANMeagan & Eric 273.109<br>
FRAVanessa & Morgan 257.454<br>
JPNNarumi & Ryuichi 246.563<br>
JPNCathy & Chris 352.003<br>
UKRSiobhan & Dmitri 349.192<br>
CHNXintong &Xun 347.881<br>
RUSYulia LIPNITSKAYA 472.9010<br>
ITACarolina KOSTNER 470.849<br>
JPNMao ASADA 464.078<br>
UKRJulia & Yuri 246.342<br>
GBRStacey & David 244.701<br>
USAMeryl &Charlie 375.9810<br>
CANTessa & Scott 372.989<br>
RUSEkaterina & Dmitri 370.278<br>
FRANathalie & Fabian 369.157<br>
ITAAnna & Luca 364.926<br>
GERNelli & Alexander 358.045<br>
GBRPenny & Nicholas 352.934<br>
USAAshley WAGNER 463.107<br>
CANKaetlyn OSMOND 462.546<br>
GBRJenna MCCORKELL 450.091<br>
The first three letters represent the team.
the rest of the text is the the competitors name.
The last digit is the score the competitor recived.
Code so far:
import java.util.Arrays;
public class project2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] array = new String[41];
String[] info = new String[41];
String[] stats = new String[41];
String[] team = new String[41];
//.txt file location
FileInput fileIn = new FileInput();
fileIn.openFile("C:\\Users\\O\\Desktop\\turn in\\team.txt");
// txt file to array
int i = 0;
String line = fileIn.readLine();
array[i] = line;
i++;
while (line != null) {
line = fileIn.readLine();
array[i] = line;
i++;
}
//Splitting up Info/team/score into seprate arrays
for (int j = 0; j < 40; j++) {
team[j] = array[j].substring(0, 3).trim();
info[j] = array[j].substring(3, 30).trim();
stats[j] = array[j].substring(36).trim();
}
// Random stuff i have been trying
System.out.println(team[1]);
System.out.println(info[1]);
System.out.println(stats[1]);
MyObject ob = new MyObject();
ob.setText(info[0]);
ob.setNumber(7, 23);
ob.setNumber(3, 456);
System.out.println("Text is " + ob.getText() + " and number 3 is " + ob.getNumber(7));
}
}
I'm pretty much stuck at this point because I am not sure how to add each teams score together.
This looks like homework... First of all you need to examine how you are parsing the strings in the file.
You're saying: the first 3 characters are the country, which looks correct, but then you set the info to the 4th through the 30th characters, which isn't correct. You need to dynamically figure out where that ends and the score begins. There is a space between the "info" and the "stats," knowing that you could use String's indexOf function. (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int))
Have a look at Maps.
A map is a collection that allows you to get data associated with a key in a very short time.
You can create a Map where the key is a country name, with value being the total points.
example:
Map<String,Integer> totalScore = new HashMap<>();
if (totalScore.containsKey("COUNTRYNAME"))
totalScore.put("COUNTRYNAME", totalScore.get("COUNTRYNAME") + playerScore)
else
totalScore.put("COUNTRYNAME",0)
This will add to the country score if the score exists, otherwise it will create a new totalScore for a country initialized to 0.
Not tested, but should give you some ideas:
public static void main(String... args)
throws Exception {
class Structure implements Comparable<Structure> {
private String team;
private String name;
private Double score;
public Structure(String team, String name, Double score) {
this.team = team;
this.name = name;
this.score = score;
}
public String getTeam() {
return team;
}
public String getName() {
return name;
}
public Double getScore() {
return score;
}
#Override
public int compareTo(Structure o) {
return this.score.compareTo(o.score);
}
}
File file = new File("path to your file");
List<String> lines = Files.readAllLines(Paths.get(file.toURI()), StandardCharsets.UTF_8);
Pattern p = Pattern.compile("(\\d+(?:\\.\\d+))");
List<Structure> structures = new ArrayList<Structure>();
for (String line : lines) {
Matcher m = p.matcher(line);
while (m.find()) {
String number = m.group(1);
String text = line.substring(0, line.indexOf(number) - 1);
double d = Double.parseDouble(number);
String team = text.substring(0, 3);
String name = text.substring(3, text.length());
structures.add(new Structure(team, name, d));
}
}
Collections.sort(structures);
List<Structure> topFive = structures.subList(0, 5);
for (Structure structure : topFive) {
System.out.println("Team: " + structure.getTeam());
System.out.println("Name: " + structure.getName());
System.out.println("Score: " + structure.getScore());
}
}
Just remove <br> from your file.
Loading file into memory
Your string splitting logic looks fine.
Create a class like PlayerData. Create one instance of that class for each row and set all the three fields into that using setters.
Keep adding the PlayerData objects into an array list.
Accumulating
Loop through the arraylist and accumulate the team scores into a hashmap. Create a Map to accumulate the team scores by mapping teamCode to totalScore.
Always store row data in a custom object for each row. String[] for each column is not a good way of holding data in general.
Take a look in File Utils. After that you can extract the content from last space character using String Utils e removing the <br> using it as a key for a TreeMap. Than you can have your itens ordered.
List<String> lines = FileUtils.readLines(yourFile);
Map<String, String> ordered = new TreeMap<>();
for (String s : lines) {
String[] split = s.split(" ");
String name = split[0].trim();
String rate = splt[1].trim().substring(0, key.length - 4);
ordered.put(rate, name);
}
Collection<String> rates = ordered.values(); //names ordered by rate
Of course that you need to adjust the snippet.
I have a csv dataset like this:
A, 10, USA
B,30, UK
C,4,IT
A,20,UK
B,10,USA
I want to read this csv lines and provide the following output:
A has ran 30 miles with average of 15.
B has ran 30 miles with average of 20.
C has ran 4 miles with average of 4.
I want to achieve this in Java. I have done this in C# by using Linq:
var readlines = File.ReadAllLines(filename);
var query = from lines in readlines
let data = lines.Split(',')
select new
{
Name = data[0],
Miles = data[1],
};
var values = query.GroupBy(x => new {x.Name}).Select(group => new { Person = group.Key, Events = group.Sum(g =>Convert.ToDouble(g.Miles)) ,Count = group.Count() });
I am looking to do this in Java, and I am not sure if I can do this without using any third party library or not? Any ideas?
So far, my code looks like this in Java:
CSVReader reader = new CSVReader(new FileReader(filename));
java.util.List<String[]> content = reader.readAll();
String[] row = null;
for(Object object:content)
{
row = (String[]) object;
String Name = row[0];
String Miles = row[1];
System.out.printf("%s has ran %s miles %n",Name,Miles);
}
reader.close();
}
I am looking for a nice way to get the total milage value for each name to calculate for the average.
As a C# developer, it is hard sometimes not to miss the features of linq. But as Farlan suggested you could do something like this:
CSVReader reader = new CSVReader(new FileReader(filename));
java.util.List<String[]> content = reader.readAll();
Map<String, Group> groups = new HashMap<>();
for(String[] row : content)
{
String Name = row[0];
String Miles = row[1];
System.out.printf("%s has ran %s miles %n", Name, Miles);
if (groups.containsKey(Name)){
groups.get(Name).Add(Double.valueOf(Miles));
} else {
Group g = new Group();
g.Add(Double.valueOf(Miles));
groups.put(Name, g);
}
}
reader.close();
for (String name : groups.keySet())
{
System.out.println(name + " ran " + groups.get(name).total() + " with avg of " + groups.get(name).average());
}
}
class Group {
private List<Double> miles;
public Group()
{
miles = new ArrayList<>();
}
public Double total(){
double sum = 0;
for (Double mile : miles)
{
sum += mile;
}
return sum;
}
public Double average(){
if (miles.size() == 0)
return 0d;
return total() / miles.size();
}
public void Add(Double m){
miles.add(m);
}
}
Use Java's BufferedReader class:
BufferedReader in = new BufferedReader(new FileReader("your.csv"));
String line;
while ( (line = in.readLine()) != null) {
String [] fields = line.split(",");
System.out.println(fields[0] + " has ran " + fields[1] + " miles with average " + fields[2]);
}
There are quite a few ways to do this, some long-winded approaches, some shorter. The issue is that Java can be very verbose for doing simple tasks, so the better approaches can be a bit uglier.
The example below shows you exactly how to achieve this, par the printing. Bear in mind however, it might not be the best approach but I feel its more of the easier ones to read and comprehend.
final File csvFile = new File("filename.csv");
final Scanner reader = new Scanner(csvFile);
final Map<String, Integer> info = new HashMap<>(); //Store the data
//Until there is are no more lines, continue
while (reader.hasNextLine()) {
final String[] data = reader.nextLine().split(","); // data[0] = A. [1] = 10. [2] = USA
final String alpha = data[0];
if (!info.containsKey(alpha)) {
info.put(alpha, Integer.parseInt(data[1]));
} else {
int miles = info.get(alpha);
info.put(alpha, miles + Integer.parseInt(data[1]));
}
}
reader.close();
The steps involved are simple:
Step 1 - Read the file.
By passing a File into the Scanner object, you set the target parsing to the File and not the console. Using the very neat hasNextLine() method, you can continually read each line until no more exist. Each line is then split by a comma, and stored in a String array for reference.
Step 2 - Associating the data.
As you want to cumulatively add the integers together, you need a way to associate already passed in letters with the numbers. A heavyweight but clean way of doing this is to use a HashMap. The Key which it takes is going to be a String, specifically A B or C. By taking advantage of the fact the Key is unique, we can use the O(1) containsKey(String) method to check if we've already read in the letter. If its new, add it to the HashMap and save the number with it. If however, the letter has been seen before, we find the old value, add it with the new one and overwrite the data inside the HashMap.
All you need to do now is print out the data. Feel free to take a different approach, but I hope this is a clear example of how you CAN do it in Java.
Maybe you could try this Java library: https://code.google.com/p/qood/
It handles data without any getter/setters, so it's more flexible than LINQ.
in your case, file "D:/input.csv" has 3 columns:
NAME,MILES,COUNTRY
A, 10, USA
B,30, UK
C,4,IT
A,20,UK
B,10,USA
the query code would be:
final QModel raw = QNew.modelCSV("D:/input.csv")
.debug(-1);//print out what read from CSV
raw.query()
.selectAs("OUTPUT",
"CONCAT(NAME,' has ran ',SUM(MILES),' miles with average of ',MEAN(MILES),'.')")
.groupBy("NAME")
.result().debug(-1)//print out the result
.to().fileCSV("D:/output.csv", "UTF-8");//write to another CSV file