Reading text file with multiple columns with logic - java

I'm reading a text file that has multiple columns and I'm storing the information in an array
File looks like this
Player | Team
---------| ---------
PlayerA | Team1
PlayerA | Team2
PlayerB | Team3
PlayerC | Team4
PlayerC | Team5
As you see each player has multiple teams. I am trying to read this file line by line so that at the end of the file I have a List with three players (A, B, and C) and each having their corresponding teams.
Classes:
Player - with Name and List<Team> (getter setter for both)
Team - with Name (getter and setter)
I can't figure out the logic of when to create the Player and Team classes and keep account for when the player name has changed

You can encapsulate your person and team inside two classes Person and Team..
Then, You can use a Map<Person, List<Team>> to maintain various teams for each Person..
Map<Person, List<Team>> mapping = new HashMap<>();
// Read each line from file..
// Get Person and Team object..
// Assuming that you have your `Person` object in person and `Team` object in team
// You need a Comparator for `Person` class to check for `containment`..
if (mapping.contains(person)) {
// Person already exist.. Update the list of Team he has
mapping.get(person).add(team);
} else {
// New entry.. create a new list.. and add it to map..
List<Team> teamList = new ArrayList<>();
teamList.add(team);
mapping.put(person, teamList);
}
NOTE : - You need to have a Comparator for your Person class to be compared..
I think I have given you a base to work upon.. Rest you need to workaround.. How to populate your object.. How to implement Comparator.. and all that..

Typically I would not question the validity of the model proposed but ... does not make more sense that the teams are those that have many players rather than the opposite?
Anyhow, assuming that the player name cannot be changed by a team appearing again with a different player name:
BufferedReader input = ...;
Map<String,Player> playersByName = new HashMap<String,Player>();
String line;
while ((line = input.readLine()) != null) {
String playerName;
String teamName;
// code to parse the player and team names from 'line' comes here.
Player player = playersByName.get(playerName);
if (player == null)
playersByName.put(playerName,player = new Player(playerName));
Team team = new Team(teamName);
if (!player.getTeams().contains(team))
player.getTeams().add(team);
}
The code assumes that the Player constructor creates an empty list of teams.
Although the above will work using a list to hold the teams for a player I would suggest that you use a Set instead for efficiency if the number of teams that player has can be quite big. In that case you do not need the last conditional, you could add directly.
Even better if you hide the List or Set implementation entirely and you add operations to manipulate the team list safely within the Player class.
Remeber that if you use a (hashed) Set solution (hidden or exposed) you'll need to override the equals and hashCode functions appropriately in the Team class (delegating them on its name would work very well).

Related

Checking if an ArrayList exists in a map

My football team has 5 different teams and I am trying to make a program to keep a track of which players are registered with each team. I want to be able to add a new player but first the program checks if that player is already registered. I would also be able to add new teams in the future and again I would like to check if that team already exists.
I have made a Map variable with
private Map<String, List<Player>> teamName;
then initialised this in the constructor
teamName = new HashMap<>();
I then have a method to add new teams and new players, I want the method to check if the Club name already exists and then if it does exist, add the player name to that Club. if it doesn't exist then I want the program to add a new Club and then add that player to that club.
So far I have a method for adding a new player,
public void newPlayer(String club, Player name) {
}
I am not sure how I now go about checking that an ArrayList exists for club and if it does add name to this list, if club does not exist then I want to make a new list and add name to it.
if I then run the program and write,
Player jamesAtkinson = new Player();
newPlayer("first team", jamesAtkinson);
it would check if there is a List in the Map called 'first team' and then either add James Atikinson to it, or create a new List called first team and then add James Atkinson.
Is this even possible to do?
Although there are a few problems with code you've provided in the question. What you're looking for is the .containsKey function that hangs off of the Map interface.
if (players.containsKey("first team") {
// Do something
} else {
List<Player> firstTeam = new ArrayList<>();
firstTeam.add(jamesAtikson);
players.put("first team", jamesAtikson);
}

java how to add variables to an object from a string

I have two objects that are being stored in arrays:
Game(String creator, String title, int releaseYear, int NumberSold)
Creator(String name, String gamesWorkedOn)
Game(creator) has multiple creators, so is stored as a string like this: "creator1, creator2, creator3" using commas to separate their values.
Not all games have multiple creators and there are not many different creators in total.
What I am trying to do is loop through an array of Game(games) and extract a creator variable from it and assign it to the Creator(name) and then match any games that creator is mentioned in and assign those title variables to Creator(gamesWorkedOn).
So far I have this:
public static void PopulateCreators(ArrayList<Game> games) {
//populating an array of Creators with games they have worked on
boolean match = false;
String thisCreator;
String gamesWorkedOn;
ArrayList<Creator> creatorArray = new ArrayList<Creator>();
for (int i = 0; i < games.size(); i++) {
thisCreator = games.get(i).getGameCreator();
thisCreator = thisCreator.replaceAll(", ", "\n");
Which gives me this output using a sysout:
Shigeru Miyamoto
Satoshi Tajiri
Yoshiaki Koizumi
Koichi Hayashida
Shigeru Miyamoto
My desired output would be to have something like this:
name = "Shigeru Miyamoto"
gamesWorkedOn = "game1, game2, game3"
I am looking at using a for loop but am unsure on how to implement it here.
Edit:
I forgot to mention a couple of details that I didn't think were important but I will be a bit clearer now. This is a Swing based project I am working on that takes user inputs and stores these arrays which are then saved into a JSON file that is read upon loading of the application and when a user clicks a 'save' button.
What you seem to want to do is map the creators to all the games that they have created or helped create. I'm going to start by creating a simplified version of the problem.
You have a list of:
class Game {
Set<Creator> creators;
}
which you want to convert to:
Map<Creator, Set<Game>> createdGames; // Map of creator name to games created
The first thing to do here is to find all of the unique creators to start adding to the map. This can be done with the stream API.
createdGames = gameList.stream().flatMap(game -> game.creators.stream()).distinct().collect(Collectors.toMap(Function.identity(), v -> new HashSet<>()));
Now you can just loop through all the games again and add the game to a creator's set if they took part in the creation of that game.
for(Game game : gameList) {
for(Creator creator : createdGames.keySet()) {
if(game.creators.contains(creator)) {
createdGames.get(creator).add(game);
}
}
}

I need to sort games in an array using title, developer, genre, etc

I am not sure how to do much with arrays yet and can't figure this out. Here is the full assignment.
Write a JAVA program that maintains a list of computer games using an array. Your main program should display the following menu repeatedly.
i. insert game
s. search game
p. print list
q. Quit
Select:
The array stores a list of computer games and each game in the list consists of title(string, key), developer(string), genre(string), year of production(int), and price(float). The list should be maintained in the increasing order of the key(title).
Option i should read a game(title, developer, genre, year, price) and insert the game into the array. Note that the new game should be inserted into the right spot so that the entire array may remain sorted. Sorting entire array again after adding the new game at the end of the array is costly and hence not acceptable. Option s asks for a game title and lists all the games matching with the title entered. Note that two or more games may have the same title. Option p simply lists all the games stored in the array.
We will assume a maximum of 100 games.
And here is what I have so far
package lab12;
import java.util.Scanner;
// create second class to hold methods
class next {
// create "insert game" method
public void insert( ) {
System.out.println("Insert");
}
// create "search game" method
public void search( ) {
System.out.println("Search");
}
// create "print list" method
public void print( ) {
System.out.println("Print");
}
// create method to
}
public class Lab12 {
public static void main(String[] args) {
Scanner in = new Scanner( System.in );
// create string to see what user wishes to do
String choose;
// create instance of other class
next choice = new next();
do {
// see which method user wants to use
System.out.print("Do you want to insert game (i) or search game (s) "
+ "or print list (p) or quit (q)? ");
// create string to see which method to go to
choose = in.nextLine();
// send user to correct method
if ( choose.equals("i") || choose.equals("I"))
choice.insert();
else if ( choose.equals("s") || choose.equals("S") )
choice.search();
else if ( choose.equals("p") || choose.equals("P") )
choice.print();
} while ( choose.equals("i") || choose.equals("s") || choose.equals("p")
|| choose.equals("I") || choose.equals("S") || choose.equals("P"));
}
}
I'm not sure how to sort the games in the array, it says to sort it by key but I don't know how to put in the key with the string. I'm not good with arrays either so I don't know how you can have all of the information linked together.
Thank you for all of your help!
Sincerely,
A stressed out college student.
Like Nimble Fungus stated, the first step is to create a Game class that will be your object representing games in your array.
If you're not concerned about efficiency, the Collections library had a built-in sorting method you can use. If you do need to worry about efficiency (for example, a massive data set) you should look into implementing a more advanced sorting algorithm. Although, I'm fairly certain Collections.sort implements Merge Sort, which should suffice in most situations.
To use Collections.sort on a datastructure containing objects, you must provide a Comparator in the method call:
Collections.sort(array, comparator);
For information on creating and using a comparator object, check out the documentation .
Also, if you plan on only using this comparator once, I might recommend creating an anonymous class, rather than creating a whole new class in your project. Here is the documentation for creating and using anonymous classes.
One last point to mention is that rather than creating a new comparator, you could actually have your Game class implement Comparable which would allow you to define the natural ordering of your Game objects at their creation.
John, create a POJO with all four parameters.
Sort the array or list on each insert using comparator. Use below link to know more .
http://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator
Or u can even use sorted map with key as game name .

Edit Specific Instance of Object

Say i let players create teams and creating a team calls a new instance of the team class which has an array list called members.
Now in the main class how would i add a player to a team after being invited? i have an addPlayer method in the team class that simply add them to the arraylist but what if there are currently multiple instances of the teams class(other players have created teams) how would it know which one to join?
I do have a variable in the Teams class for the teamLeader which gets set when creating the instance if that could help me edit a certain instance.
Team team = new Team(this, leader);
Any help is appreiciated
You need an identifier to uniquely distinguish each team and you can use that identifier to store the teams in a Map. Something like this:
Map<String,Team> teamMap = new HashMap<String,Team>();
Chose the key type as per your requirement, I chose String for an example
As per your design, You need to keep all teams in a list after creation.
ArrayList teamsList=new ArrayList ();
Team team = new Team(this, leader);
teamsList.add(team);
Then Loop through all teams in addPlayer method and then compare leader and then add a player to it. Something like this -
public void addPlayer (Player player,String leader){
for(int i=0; i<teamListSize;i++)
Team tempTeam=teamsList.get(i);
if(tempTeam.getLeader().equalsIgnoreCase(leader)){
tempTeam.add(player);
break;
}
}

Keeping track of scores in Java

I'm new to Java and I'm currently writing a program for an assignment that represents a 'sports league' (classes to represent player/club/match/league)
My main problems are occurring in the league class. Here are the relevant variables to give you an idea how I'm storing things:
public class League
{
private String leagueName;
private ArrayList<Club> clubs;
private ArrayList<Match> fixtures;
private ArrayList<String> results2;
private TreeMap<Match, String> results;
private String topTeam;
private String goldenBoot;
}
Currently trying to write a method in the League class which will print a 'league table' - i.e. a list of Clubs sorted by their points tally (held as variable in Club class) and I'm drawing a blank on it.
Further to this, I need to write two methods to find the top scorer (golden boot) and find the top team in the league; again I am drawing a blank. Perhaps I am overcomplicating things?
Would be very grateful for suggestions/sample methods
EDIT:
Ok, so that method I'm trying to write is something beginning with:
public void getLeagueTable() {
for(Club c : clubs) {
c.getTally();
}
}
which would give the tally value for each Club object - but how to sort these results, and how to associate the highest with one Club is what's really troubling.
To print the league table, you are going to need to sort the club array and then loop through each item and print the club name.
To sort the club array try using Collections.sort http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html
.. that is assuming you havent been told to implement your own algorithm
Again, more sorting required to get the top team and top scorer, then you will need to pick the top item from the sorted list.
Hope that helps...
You better use Set rather than ArrayList. And here is a good start for your question :
void printLeagueTable(){
i = 0 ;
while( i != clubs.size() ){
Club club = clubs.get(i);
System.out.println("club: "+i+ "points: " club.points() );
}
}

Categories