Format an arraylist - java

I have a file that I am storing into an ArrayList and I can't figure out how to format it so that certain Strings of text are stored in particular indexes. The first line will be the category, second line the question and 3rd the answer to trivia questions. I need to do this so that I can then randomly pick questions then check the answers for a trivia game. All I get so far is every word separated by a comma. From the professor,
"The input file contains questions and answers in different categories. For each category, the first line indicates the name of the category. This line will be followed by a number of pairs of lines. The first line of the pair is the question, and the second line is its corresponding answer.
A blank line separates the categories."
Here is my code so far:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class TriviaGamePlayer {
/**
* #param args
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ArrayList<String> triviaQuestion = new ArrayList<String>();
Scanner infile = new Scanner(new File("trivia.txt"));
while(infile.hasNext()){
triviaQuestion.add(infile.next());
}
System.out.println(triviaQuestion);
}
}

From what I can see in the question so far, You would be best off creating your own TriviaQuestion Object which would look something like
public class TriviaQuestion
{
public String question;
public String answer;
public boolean asked;
public String category;
TriviaQuestion (String q, String a, String c)
{
question = q;
answer = a;
category = c;
}
}
Then you have a few options, but if you have this Object then everything becomes a bit easier. I would create a Map<String,List<TriviaQuestion>> where the key is your category.
Then when reading the file, also you should use infile.hasNextLine() and inFile.nextLine()
Read a line (first I assume would be the category)
Read next two lines (question and answer)
Create new instance `new TriviaQuestion( question, answer, category)'
Add this to the Array list
Repeat until blank
If next line is blank, add list to map and loop back to (1)
Like: (this is assuming well formed file)
String line = inFile.nextLine(); //first line
String category = line;
while(infile.hasNextLine())
{
line = inFile.nextLine();
if(line.isEmpty()) //blank line
category = inFile.nextLine();
else
{
String q = line;
String a = inFile.nextLine();
//do other stuff
}
}
Then to ask a question get the list for the category, choose a random question then set it to asked so it doesn't come up again
ArrayList<TriviaQuestion> questions = yourMap.get("Science");
Integer aRandomNumber = 23 //(create a random Number using list size)
TriviaQuestion questionToAsk = questions.get(aRandomNumber)
System.out.println(questionToAsk.question)
questionToAsk.asked = true

I would approach this problem by identifying what is needed. You have a list of categories (Strings). Within each category, there will be a list of question (String) and answer (String) pairs. From there we already see some "logical" ways to organize the data.
Questions - String
Answers - String
Question/Answer pairs - Write a class (for now, lets refer to it as QAPair) with two Strings as fields (one for the question, one for the answer)
List of Q/A pairs within a category - ArrayList
List of Categories, mapped to a list of Q/A pairs - Maybe a Map would do the trick. The type would be: Map>
From there you would start parsing the file; for the first line, or after a blank line is encountered, you know the String will give a category name. You can call containsKey() to check if the category name already exists; if it does fetch the ArrayList of Q/A Pairs for that category and keep adding to the list, otherwise initialize a new ArrayList and add it to the map for that category.
You could then read a pair of lines. For each pair of lines you read initialize a QAPair object, then add it to the ArrayList for the category they belong to.
Here's an example of using a Map:
Map<String, ArrayList<QAPair>> categories = new HashMap<String, ArrayList<QAPair>>();
if (!categories.containsKey("Math")) { // Check to see if a Math category exists
categories.put("Math", new ArrayList<QAPair>()); // If it doesn't, create it
}
QAPair question1 = new QAPair("2+2", "4");
// get() method returns the ArrayList for the "Math" category
// add() method adds the QAPair to the ArrayList for the "Math" category
categories.get("Math").add(question1);
To get the list of categories from a map and pick one:
// Convert to an array of Strings
String[] catArray = categories.toArray(new String[0]);
// Get the 10th category in the array
// Use catArray.length to find how many categories there are total
catArray[10];

Related

Trying to link objects in 2 seperate Array Lists

Thank you for taking the time to look at this. I am having some trouble with a project of mine. As of now I have 2 array lists that collect names and ids. I want to link the objects of both lists (the name and id) with each other so that I can perform a insertion sort algorithm later.
Tasks:
1) Ask the user to input names and IDs for team members. Users should alternate inputting names and IDs on separate lines, as shown in the sample run below. As the information is provided, TeamMembers will be added to an ArrayList of TeamMember objects. Remember that names should be stored in title case inside of the TeamMember class.
2)The user should enter the word "STOP" in any combination of lowercase and uppercase letters to stop entering team member information.
3)Sort the ArrayList in increasing order by ID using the insertion sort algorithm. You can choose to use the insertion sort algorithm as you are inserting each new TeamMember object into the array, or you can wait until the entire array is constructed before sorting all of its members at once.
4)After all the names are entered and sorted, print the contents of the ArrayList using ArrayList.toString().
package com.company;
import java.util.*;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
String inputName;
String inputID;
List<String> fullName = new ArrayList<String>();
List<String> idString = new ArrayList<String>();
while (!(fullName.contains("stop"))) {
Scanner uInput = new Scanner(System.in);
//String checkInput = "test";
System.out.println("Please enter the name: ");
inputName = uInput.nextLine();
fullName.add(inputName.toLowerCase());
// System.out.println("List: " + fullName); //Check what is in the fullName List
// System.out.println("List Size: " + fullName.size()); // Check the size of fullName ArrayList
System.out.println("Please enter the ID: ");
inputID = uInput.nextLine();
idString.add(inputID.toLowerCase());
}
fullName.remove(fullName.size() - 1); //removing the last word, which is always "stop"
idString.remove(idString.size() - 1); //(Same as above)
//insertionSort(fullName);
//insertionSort(idString);
}
HashMap newmap = new HashMap(); //creating hash map
Best, Nate
As the information is provided, TeamMembers will be added to an ArrayList of TeamMember objects
So, you need to have a TeamMember class that has the names and ids
class TeamMember {
private String name;
private String id;
public TeamMember(String name, String id) {
this.name = name;
this.id = id;
}
}
Remember that names should be stored in title case inside of the TeamMember class.
Refer to this post for converting a String to title case
Clues for rest of your work:
The user should enter the word "STOP" in any combination of lowercase and uppercase letters to stop entering team member information.
After getting the name, use String's equalsIgnoreCase to check if the entered String is a variation of STOP.
Sort the ArrayList in increasing order by ID using the insertion sort algorithm.
Either you must pass a Comparator (to the sorting method) or make TeamMember implement Comparable to compare two TeamMember objects

Ignore numbers in a text file when scanning it in Java

I am doing an assignment in Java that requires us to read two different files. One has the top 1000 boy names, and the other contains the top 1000 girl names. We have to write a program that returns all of the names that are in both files. We have to read each boy and girl name as a String, ignoring the number of namings, and add it to a HashSet. When adding to a HashSet, the add method will return false if the name to be added already exists int he HashSet. So to find the common names, you just have to keep track of which names returned false when adding. My problem is that I can't figure out how to ignore the number of namings in each file. My HashSet contains both, and I just want the names.
Here is what I have so far.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Names {
public static void main(String[] args) {
Set<String> boynames = new HashSet<String>();
Set<String> girlnames = new HashSet<String>();
boynames = loadBoynames();
System.out.println(girlnames);
}
private static Set<String> loadBoynames() {
HashSet<String> d = new HashSet<String>();
File names = new File("boynames.txt");
Scanner s = null;
try {
s = new Scanner(names);
} catch (FileNotFoundException e) {
System.out.println("Can't find boy names file.");
System.exit(1);
}
while(s.hasNext()){
String currentName = s.next();
d.add(currentName.toUpperCase());
}
return d;
}
}
My plan is to take the HashSet that I currently have and add the girl names to it, but before I do I need to not have the numbers in my HashSet.
I tried to skip numbers with this code, but it just spat out errors
while(s.hasNextLine()){
if (s.hasNextInt()){
number = s.nextInt();
}else{
String currentName = s.next();
d.add(currentName.toUpperCase());
}
}
Any help would be appreciated.
You could also use regex to replace all numbers (or more special chars if needed)
testStr = testStr.replaceAll("\\d","");
Try to use StreamTokenizer (java.io) class to read file. it will split your file into tokens and also provide type of token like String value, number value in double data type, end of file, end of line). so you can easily identify the String token.
You can find details from here
http://docs.oracle.com/javase/6/docs/api/java/io/StreamTokenizer.html

How to replace authors names with unique numbers in java using hashmap

I have a CSV file which is a coauthorship network.Entries are like this:
1992,M_DINE,R_LEIGH,P_HUET,A_LINDE,D_LINDE
1992,C_BURGESS,J_CLINE,M_LUTY
1992,M_DINE,R_LEIGH,P_HUET,A_LINDE,D_LINDE
1992,F_ZWIRNER
1992,O_HERNANDEZ
...
I want to replace all the authors names with unique numbers using hashmaps
I want the output to be sth like this:
M_DINE 1
R_LEIGH 2
P_HUET 3
...
and I do not want the years to be included.
Maintain a collection of author names, Read each line, split on comma, discard year, for each author if collection does not contain author name then add it to the collection. Then read from the collection and assign number.
Conceptually, you've explained everything you want to do.
You'll need a few objects.
HashMap<String, Integer> authorList = new HashMap<>();
int authorCounter = 0;
The map, obviously, and a counter to track your index.
I don't know what your main method is, but you need to process the input.
public void foo() {
// ... handle the file import through scanner in
while(in.hasNext()) {
String input = in.next();
String[] authors = input.split(',');
for(int i = 1; i < authors.length; i++) { //skip index 0 because that's the year
addAuthor(authors[i]);
}
}
}
This is a really plain addAuthor function. You probably want to extract it into hasAuthor and getAuthorId and so on, but this will just add an author if it doesn't find it with the latest iterated counter.
void addAuthor(String s) {
if(authorList.get(s) == null)
authorList.put(s, ++authorCounter);
}

Iterate through multiple array lists with same index

Im a beginner in Java. I have 3 ArrayLists and all of the ArrayLists contain data pertaining to a specific subject and hence have the same length. I want to iterate through the array and perform some operations as illustrated below:
public void example(){
ArrayList<Long> ID = new ArrayList<Long>;
ArrayList<Integer> AcNo = new ArrayList<Integer>;
ArrayList<Integer> Vnum = new ArrayList<Integer>;
//get ID and AcNo from user, compare it in the ArrayList, get the corresponding Vnum
// for the Vnum from previous step, compare it with the next Vnum and get corresponding ID and AcNo until some *condition* is satisfied.
}
How do I do this in Java? I saw examples of Iterator, but Im not sure about the correct method to do this! Please help.
If all three lists are of the same length, then iterate over them using for loop with indexes. Same indexes represents the same user in each of the three lists:
for (int i=0; i<ID.size(); i++) {
Long userId= ID.get(i);
Integer userAcNo= AcNo.get(i);
Integer userVnum= Vnum.get(i);
//if the next user exist, get the next user
if (i + 1 < ID.size()) {
Long nextUserId= ID.get(i+1);
Integer nextUserAcNo= AcNo.get(i+1);
Integer nextUserVnum= Vnum.get(i+1);
//now compare userVariables and nextUser variables
}
}
A better approach would be to have a single list of Subject objects or similar, so that each Subject contains all relevant data about itself.
class Subject {
private final long id;
private final int acNo;
private final int vnum;
/* Appropriate constructor and getters... */
}
You might also want to consider renaming the fields so that they are more descriptive.

Creating function to have parameter to create multiple JRadioButton

I am trying to create a java function where it takes 2 parameter. One is comma delimited list of string that represent what will be called for radio button. Second is comma delimited list of string that represents the variable respected to 1st parameter.
For example, If I write f1("apple,banana", "a,b"), I wanted to make JRadioButton with apple and banana along with a and b being their variable.
Is this possible?
I tried to use split(",") but I did not get too far...
Thanks in advance!
EDIT: I came up with following but still now luck..
static void f5(String question, String rbLabel, String rbVar, String help)
{
JOptionPane.showInputDialog(question);
ArrayList<String> rbLabelAL = new ArrayList<String>();
ArrayList<String> rbVarAL = new ArrayList<String>();
String[] token;
String[] token2;
token = rbLabel.split(",");
token2 = rbVar.split(",");
if(token.length == token2.length)
{
for(int i=0;i<token.length;i++)
{
rbLabelAL.add(token[i]);
rbVarAL.add(token2[i]);
}
}
JRadioButton(rbLabelAL(0));
}
Following up on my comment....if you wanted to do something like this, I would suggest creating an arraylist.
Something like.... ArrayList<String> options = new ArrayList<String>();
Add in your options....options.add("apple");
Then pass the arraylist into your method and create the radio buttons as such...JRadioButton(options(i));
Of course you would have to iterate through the list to create all buttons.

Categories