creating new ArrayList with elements from another one - java

I'm writing the code of my first Java game right now and I have a problem with ArrayList. I have one, with elements like nicknames and scores, to be specific I create it from the text file(code below):
static ArrayList<String> results = new ArrayList<String>();
BufferedReader br = new BufferedReader(new FileReader(ranking));
String line = br.readLine();
results.add(line);
while(line != null) {
line = br.readLine();
results.add(line);
}
br.close();
So the file looks like this:
nick1
score1
nick2
score2
...
I would like to make a ranking with top 10 best results, my idea is to make the class with the fields nick and score and somehow assign that fields to appriopriate ones from the ArrayList. Maybe I can do this like this:(?)
for(int i = 0;i<results.size();i=i+2){
nick = results.get(i);
}
for(int i = 1;i<results.size();i=i+2){
score = results.get(i);
}
Then I would create a new ArrayList, which would be in the type of that new class. But my problem is that I don't exactly know how I can connect values from 'old' ArrayList with the paramaters of future type of new ArrayList. The new one should be like:
static ArrayList<Ranking> resultsAfterModification = new ArrayList<Ranking>();
Ranking rank = new Ranking(nick, score);
Then I can easily compare players' scores and make a solid ranking.

You can create a class Player that contains the name and score of each player. The Player class should implement the Comparable interface which is Java's way of figuring out the logical order of elements in a collection:
public class Player implements Comparable<Player>
{
private String _name;
private double _score;
public Player(String name, double score)
{
this._name = name;
this._score = score;
}
public String getName()
{
return this._name;
}
public double getScore()
{
return this._score;
}
// Since you probably want to sort the players in
// descending order, I'm comparing otherScore to this._score.
#Override
public int compareTo(Player otherScore)
{
return Double.compare(otherScore._score, this._score);
}
#Override
public String toString()
{
return "Name: " + this._name + ", Score: " + Double.toString(this._score);
}
}
Once you've created the Player class, you can read both name and score in one go and use the Collections utility class to sort the Player list. Last but not least, you could grab the top ten by using the subList method: (this assumes that the file will have a score for each name and the file will be in the format you specified above)
public static void main(String[] args)
{
List<Player> results = new ArrayList<Player>();
BufferedReader br;
try
{
br = new BufferedReader(new FileReader("myFile.txt"));
String line = br.readLine();
while(line != null)
{
String name = line;
double score = Double.parseDouble(br.readLine());
results.add(new Player(name, score));
line = br.readLine();
}
br.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
// Sort using the java.util.Collections utility class
// Sorting will modify your original list so make a copy
// if you need to keep it as is.
Collections.sort(results);
// Top 10
List<Player> top10 = results.subList(0, 10);
}

1) You should program by Interface (List instead of ArrayList in declared type) here because you don't use methods specific to ArrayList.
List<Ranking> resultsAfterModification = new ArrayList<Ranking>();
2)
Then I would create a new ArrayList, which would be in the type of
that new class. But my problem is that I don't exactly know how I can
connect values from 'old' ArrayList with the paramaters of future type
of new ArrayList.
To do it, you don't need many changes.
Your idea a is little too complex because finally you perform two mappings : one where you store from read line to List of String and another one where you store from List of String to List of Ranking .
You can direct map read line to List of Ranking.
List<Ranking> rankings = new ArrayList<Ranking>();
BufferedReader br = new BufferedReader(new FileReader(ranking));
String nick = null;
while ( (nick = br.readLine()) != null){
String score = br.readLine();
rankings.add(new Ranking(nick, score));
}

You can save array in file :
1 use, FileInputStram and FileOuputStream to write and read array object to file.
2 use Gson library to save and load array as json
3 write as normal textfile like below:
Player 1
Score 1
Player 2
Score 2
....
ArrayList<Player> list=new ArrayList();
Scanner sc=new Scanner(new File("filepath.txt"));
While(sc.hasNextLine()){
Player p=new Player();
p.name=sc.nextLine();
If(sc.hasNextFloat()){
p.score=sc.nextFloat();
list.add(p);
}
}
Arrays.sort(list,...);
And can sort array by Arrays.sort()

So your Ranking class might look like
public class Ranking {
public String nick;
public int score;
}
I think the nick and score are two ArrayList containing nicks and scores respectively.
So to create a common ArrayList, if the sizes of nick and score are the same, you might do something like this.
static ArrayList<Ranking> resultsAfterModification = new ArrayList<Ranking>();
for(int i = 0; i < nick.size(); i++) {
Ranking rank = new Ranking(nick.get(i), score.get(i));
resultsAfterModification.add(rank);
}
Now you need to write your own comparator to sort the values inside resultsAfterModification
Collections.sort(resultsAfterModification, new Comparator<Ranking>() {
#Override
public int compare(Ranking r1, Ranking r2) {
if (r1.score > r2.score)
return 1;
if (r1.score < r2.score)
return -1;
return 0;
}
});

Related

How to stop string repetition on array

We I have this college assignment where I have to Read a file with a list of names and add up to 3 presents to each one. I can do it but the presents are repeating and some people in the list are getting the same present more than once. How can I stop it so each person receives different variety of present each time?
Here is my code:
public static void main(String[] args) throws IOException {
String path = "Christmas.txt";
String line = "";
ArrayList<String> kids = new ArrayList<>();
FileWriter fw = new FileWriter("Deliveries.txt");
SantasFactory sf = new SantasFactory();
try (Scanner s = new Scanner(new FileReader("Christmas.txt"))) {
while (s.hasNext()) {
kids.add(s.nextLine());
}
}
for (String boys : kids) {
ArrayList<String> btoys = new ArrayList<>();
int x = 0;
while (x < 3) {
if (!btoys.contains(sf.getRandomBoyToy().equals(sf.getRandomBoyToy()))) {
btoys.add(sf.getRandomBoyToy());
x++;
}
}
if (boys.endsWith("M")) {
fw.write(boys + " (" + btoys + ")\n\n");
}
}
fw.close();
}
}
Just use a Set data structure instead of a List.
if (!btoys.contains(sf.getRandomBoyToy().equals(sf.getRandomBoyToy()))) {
btoys.add(sf.getRandomBoyToy());
x++;
}
Generates 3 toys, comparing 2 of them with each other first, and checking if the resulting boolean is present in the list of strings (which it presumably isn't), then appending the 3rd one.
Instead you should generate a single one, and use it for both checking and adding:
String toy = sf.getRandomBoyToy();
if(!btoys.contains(toy)) {
btoys.add(toy);
x++;
}
The set interface present in the java.util package and extends the Collection interface is an unordered collection of objects in which duplicate values cannot be stored. It is an interface which implements the mathematical set. This interface contains the methods inherited from the Collection interface and adds a feature which restricts the insertion of the duplicate elements. There are two interfaces which extend the set implementation namely
for (String boys : kids) {
Set<String> btoys = new HashSet<String>();
btoys.add(sf.getRandomBoyToy());
if (boys.endsWith("M")) {
fw.write(boys + " (" + btoys + ")\n\n");
}
}

Using Collections.sort() with an Object Array List with multiple variables

Would Collections.sort() work in sorting by Make in a Car object Array List? I'm getting no error messages after adding the null there, but my goal is to sort them by Make, specifically, but I'm not entirely sure how to go about doing that.
public void readingFromFile(String file) throws FileNotFoundException //an object array that takes in string files
{
try {
File myFile = new File(file); //converts the parameter string into a file
Scanner scanner = new Scanner(myFile); //File enables us to use Scanner
String line = scanner.nextLine(); //reads the current line and points to the next one
StringTokenizer tokenizer = new StringTokenizer(line, ","); //tokenizes the line, which is the scanned file
//counts the tokens
while (tokenizer.hasMoreTokens()){
String CarMake = tokenizer.nextToken(); //since car is in order by make, model, year, and mileage
String CarModel = tokenizer.nextToken();
int CarYear1 = Integer.parseInt(tokenizer.nextToken());
int CarMileage1 = Integer.parseInt(tokenizer.nextToken()); //converts the String numbers into integers
Car cars = new Car(CarMake, CarModel, CarYear1, CarMileage1); //since the car has a fixed order
arraylist.add(cars); //add the cars to the unsorted array
}
scanner.close(); //close the scanner
} catch (FileNotFoundException f){
f.printStackTrace();
return;
}
arraylist2.addAll(arraylist);
Collections.sort(arraylist2, null);
}
Use the streaming API:
sorted = arrayList2.stream().sorted(Comparator.comparing(Car::getMake));
Since Java 8 the List has a sort method inherited by Collection. Additionally you can use the Comparator class to create a comparator very easy:
arraylist2.sort(Comparator.comparing(Car::getMake));
If you want to use multiple Parameters for your sort you can easily append them:
arraylist2.sort(Comparator.comparing(Car::getMake)
.thenComparing(Car::getYear)
// ...
);
If you are using a Java Version below Java 8 you have to implement the sort logic yourself in an Comparator or use an external library:
Collections.sort(arraylist2, new Comparator<Car>() {
#Override
public int compare(Car a, Car b) {
return a.getMake().compareTo(b.getMake());
}
});
For multiple parameters it would look like the following:
Collections.sort(arraylist2, new Comparator<Car>() {
#Override
public int compare(Car a, Car b) {
int compareMake = a.getMake().compareTo(b.getMake());
if (compareMake != 0) {
return compareMake;
}
return a.getYear() - b.getYear();
}
});

Array Lists, reading in from file and 2 Classes

I'm learning arraylists, I'm unsure of how to read in from file and add it to a list as I am much more used to arrays, are they alike?
I'm also getting many errors when I am trying to instantiate the class object 'film' but never mind about it.
How am I able to get load my file method working? To me it looks right I think I just need a strangers pov.
Also getting an error when trying to find the file symbol. If there is any specific readings I should do for array lists could you please link me or explain best you can.
I'm very new to both coding and stack overflow so if you could dumb anything down and please be patient if I don't understand anything thanks.
import java.util.*;
public class CinemaDriver {
film[] Film;
public static void main(String[] args) {
Film = new film[100];
ArrayList <Film> list = new ArrayList<Film> ();
}
public void readFromFile() {
File f = new file("file.txt");
Scanner infile = new Scanner(f);
int x = infile.nextInt();
for(int i = 0; i < x ; i++) {
String title = infile.nextLine();
String genre = infile.nextLine();
int screenings = infile.nextInt();
int attendance = infile.nextInt();
file.nextLine();
list.add(title,genre,screenings,name);
}
infile.close();
}
public void displayAll() {
for (film f : list ){
System.out.println(f +"/ \n");
}
}
}
Your ArrayList keeps Film objects as defined here:
ArrayList <Film> list = new ArrayList<Film> ();
But you are trying to insert several different objects or values (Strings, ints, etc...) instead of a Film object
list.add(title,genre,screenings,name);
What you should do is something like this:
Option 1:
list.add(new Film(title,genre,screenings,name));
Option2:
Film f = new Film();
f.setTitle(title);
f.setGenre(genre);
f.setScreenings(screenings);
f.setName(name);
list.add(f);

Descending Order Array List

In this program I need to display an array list from an external file in descending order. Whenever I run the program though, I still get the same order of the original list. I just need help with the descending order part. I utilized the Collections methods to accomplish this task but I don't think I fully understand exactly what is going on whenever I call upon Collections, it just spits out the array list as brought in by the first array call. Any help would be greatly appreciated. I placed 4 stars at the end and beginning of the code in question.
import java.io.*;
import java.util.*;
public class ioStafford {
public static void revOrder(String x[])
{
}
public static void main(String args[])
{
try(BufferedReader fr1 = new BufferedReader(new FileReader("myImport.txt")))
{
//Create a new file for the reverse output if it doesn't exist
File f1 = new File("myOutput.txt");
//Code for new file creation
if(!f1.exists())
{
f1.createNewFile();
}
//Initialize string variables
String type;
//Array List to hold text file
ArrayList<String> names = new ArrayList<String>();
//Add text file contents to the array list
while((type = fr1.readLine()) != null)
{
names.add(type);
}
//Display array list
System.out.println("Below is the list of animals with a comma and in the original order:");
System.out.println(names);
****//Display information in descending order
Collections.sort(names, Collections.reverseOrder());
System.out.println(names);****
//Convert array list to string and replace commas
String fornames = names.toString().replace("," , " ");
//Display altered information
System.out.println("Here is the list with the commas removed:");
System.out.println(fornames);
}
catch(FileNotFoundException e)
{
System.out.println("Please utilize the file named myImport.txt please!");
}
catch(IOException e)
{
}
}
}
Try this one in a place of
Collections.sort(names, Collections.reverseOrder());
:->
Collections.sort(names, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});

Adding unique values to java 2d arrays + how to sort them?

I need your help! I have an assignment for class where I have to take sales data from an excel list, import it into java, and output a new list that has sorted the Product ID's and the amount of units sold for each product. That means if the original list has 5x Product ID "1003", the final list should only list 1x Product ID "1003" and combine the 5 different unit sales into one total number.
EDIT: I should probably show what the original excel list looks like:
ProductID......Units
10004............. 4
10002............. 2
10004 ............ 3
10008 ............ 6
10009 .............3
etc etc. So basically just combine the duplicate ID's and sum their total units sold.
I'm stuck on two things now. I'm trying to make a new multidimensional array for the final list, but I'm unable to add unique productID's. I tried doing it with a for loop, but it still adds multiples of the productID's.
ALSO, I've tried to sort the final array by the Product ID column in ascending order, but I can't get it to work.
I've put comments with CAPS LOCK to show where the two issues are!
Thanks guys!!!
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class Project1{
public static void main(String[] args) {
Project1 obj = new Project1();
obj.run();
}
public void run() {
String csvFile = "C:/Users/Jenny/Documents/Classwork/SalesData.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
int counter = 0;
int salesDataArrayCounter = 0;
int [][] finalSalesData = new int[200][2];
System.out.println("Product ID\tUnits"); //Headers for original Data
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] salesData = line.split(cvsSplitBy);
while (counter>0) //this allows me to skip first line of data (It's just text, I need the numbers)
{
System.out.println(salesData[0] + " \t\t " + salesData[1]);
int productID = Integer.parseInt(salesData[0]);
int units = Integer.parseInt(salesData[1]);
search: //THIS IS WHERE MY FIRST TROUBLE LIES
{
for (int i = 0; i < finalSalesData.length; i++)
{
if(finalSalesData[i][0]==(productID)) //Should let me find duplicate product ID's and only add the Units to a pre-existing index
{
finalSalesData[i][1] = finalSalesData[i][1] + units;
break search;
}
else //If productID is unique, add new product ID and units to a new slot in the new array
{
finalSalesData[salesDataArrayCounter][0] = productID;
finalSalesData[salesDataArrayCounter][1] = units;
salesDataArrayCounter++;
break search;
}
}
}
break;
}
counter++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("\n\nSorted Sales Data");
System.out.println("\nProductID\tUnits");
//HOW DO I SORT THIS DATA IN ASCENDING ORDER OF PRODUCT IDS?
for (int q = 0; q < finalSalesData.length; q++)
{
for (int j = 0; j < finalSalesData[q].length; j++)
{
System.out.print(finalSalesData[q][j] +"\t\t");
}
System.out.println("");
}
System.out.println("Done");
}
}
I would use a SortedMap to store the results since it sorts ascending on the key by default. This should be defined before the loop:
SortedMap<Integer,Integer> sortedFinalSalesData = new TreeMap<Integer,Integer>();
After the
int units = Integer.parseInt(salesData[1]);
you can implement something like this:
Integer currentUnits = sortedFinalSalesData.get(productID);
sortedFinalSalesData.put(productID, currentUnits != null ? units + currentUnits : units);
Look up tertiary operators if that doesn't make sense since you are supposed to learn something in a school assignment (LOL)!
Are you required to use a 2 dimensional array? It might make more sense to make a class that holds the sales information and the product ID.
Make an empty list of product objects.
With each item from the CSV, check the list to see if the product ID is already there. If it is, add the product information to the existing object. If not, add a new product object to your list.
For sorting:
Write a custom comparison method and use the built in sort function as shown here: Sort ArrayList of custom Objects by property
That second while loop in your code would make more sense as an if statement... Or just start your counter at 1.

Categories