What I'm trying to do: I have a set of golf club objects(~60 clubs). Depending on the club name and club level(1-10 levels), each one will have a different maxmultiplier and minmultiplier value associated with it that I will need to perform calculations.
What I've thought about:
Using switch statement for the club levels and a hashmap to pair the club name with an array of the multipliers in order to retrieve the correct values. Issue I have with this would be that I would have to create ~60 separate 2item arrays for the multipliers. Thought about 2d arrays and so forth but I'm at the point where it feels like I'm going in circles. I know I CAN get it to work through brute force but I'm trying to work on efficiency. Is there a way to set this up in a localized way(table-like structure) that would make it easy to retrieve?
Things to Note: Java is my first language,I'm trying to learn, I'm at the skill level where I can MAKE things work but am transitioning into learning best practices. So for answers If we could stick with basic/intermediate java ideas that would be appreciated. But after I get it working next step will be implementing serializable to store data outside the program and learning that, followed by storing information in a SQL database which ultimately seems the easiest in my mind using a table.
Here is some of my code:
/*
* Creates all the clubs to be used in the app
*/
public ClubSet() {
clubMap = new HashMap<String, String[]>(100, (float) 0.8);
clubMap.put("DRIVER", driverArray);//all the club names of driver type
clubMap.put("WOOD", woodArray);
clubMap.put("LONG", longArray);
clubMap.put("SHORT", shortArray);
clubMap.put("WEDGE", wedgeArray);
clubMap.put("ROUGH", roughArray);
clubMap.put("SAND", sandArray);
for (HashMap.Entry<String, String[]> entry : clubMap.entrySet()) {
for (String clubName : entry.getValue()) {
Club club = new Club(entry.getKey(), clubName);
this.put(club, club.getClubType());
}
}
}
/*
* Returns a set of all clubs according to clubtypre(e.g. Driver,Wood,Long
* Iron,etc)
*/
public HashSet<Club> getClubSet(String clubType) {
HashSet<Club> clubSet = new HashSet<Club>();
if (this.containsValue(clubType)) {
for (HashMap.Entry<Club, String> entry : this.entrySet()) {
if (entry.getValue().equalsIgnoreCase(clubType)) {
clubSet.add(entry.getKey());
}
}
}
return clubSet;
}
}
public class Club {
private String clubType;
private String clubName;
private int level;
private ImageIcon imageIcon;
private String rarity;
private double maxMultiplier;
private double minMultiplier;
private HashMap<String, String[]> rarityMap;
private final String[] starterArray = new String[] { "BEGINNER DRIVER", "BEGINNER WOOD", "BEGINNER LONG",
"BEGINNER SHORT", "BEGINNER WEDGE", "BEGINNER ROUGH", "BEGINNER SAND" };
private final String[] commonArray = new String[] { "ROCKET", "QUARTERBACK", "VIPER", "SNIPER", "BACKBONE",
"SATURN", "RUNNER", "CLAW", "DART", "SKEWER", "MACHETE", "DESERT STORM", "SAND LIZARD" };
private final String[] rareArray = new String[] { "EXTRA MILE", "ROCK", "BIG DAWG", "GUARDIAN", "GOLIATH",
"GRIZZLY", "APACHE", "THORN", "HORNET", "DOWN-IN-ONE", "RAPIER", "ROUGHCUTTER", "RAZOR", "NIRVANA",
"MALIBU", "HOUDINI" };
private final String[] epicArray = new String[] { "APOCALYPSE", "BIG TOPPER", "THOR'S HAMMER", "HORIZON",
"CATACLYSM", "HAMMERHEAD", "GRIM REAPER", "B52", "TSUNAMI", "KINGFISHER", "FALCON", "FIREFLY", "BOOMERANG",
"ENDBRINGER", "JUNGLIST", "OFF ROADER", "AMAZON", "CASTAWAY", "SAHARA", "SPITFIRE" };
public Club() {
this.clubType = null;
this.clubName = null;
this.level = 1;
rarity = null;
// maxMultiplier = 0;
// minMultiplier = 0;
}
public Club(String clubType, String clubName) {
this.clubName = clubName;
this.clubType = clubType;
this.level = 1;
if (Arrays.asList(starterArray).contains(clubName)) {
this.rarity = "STARTER";
} else if (Arrays.asList(commonArray).contains(clubName)) {
this.rarity = "COMMON";
} else if (Arrays.asList(rareArray).contains(clubName)) {
this.rarity = "RARE";
} else if (Arrays.asList(epicArray).contains(clubName)) {
this.rarity = "EPIC";
}
// setMultipliers(clubName);
}
Related
note: This is just a rough sketch.
I have a program that will get questions out of the database with each questions options and answers(which are 4 options). Each options will be test against the answer and if any of the options selected equals to the answer, it will be added to an array which will be created and if unanswered, it will be added to another array.
This is the rough sketch of what I have.I do not say this code is correct, but a rough sketch. Meaning , I just wanna have the idea of how to create it or go about it.
String questionAnswerOption[][] = new String[][](){
String getAllQuestions = new String();
String getAllOptions = new String();
String getAllAnswers = new String();
String getAll[][] = new String getAll[getAllOptions.lenght][getAllAnswer.lenght];
int i,j;
String query = "SELECT id,question, options, answers FROM questions WHERE year = ? AND subject = ?";
//some database command intentionally omitted
while(rs.next()){
getAllQuestions = rs.getString("questions");
getAllOptions =rs.getString("options");
getAllAnswers = rs.getString("answers");
for(i = 1; i<= getAllOptions.lenght; i++){
for(j = 1; i<= getAllAnswers.lenght; i++){
getAllOptions[i];
getAllAnswers[i];
}
}
}
}
//for the presentation because I wanna use the MVP pattern
String correct[] = new String[];
String unattempted [] = new String[];
int i, j;
if(group.getSelectedToggle().getUserOption().toString().equals answers){
correct[].add;
i++;
}elseif(group.getSelectedToggle().getUserOption().toString().!equals answers){
unattempted[].add;
j++;
}
Just a rough sketch:
Retrieving a Quiz from the database:
interface QuizDao {
Quiz getQuiz();
}
A quiz providing access to all questions. Questions answered correctly or not can be implemented as filters.
interface Quiz {
Collection<Question> getAllQuestions();
Collection<Question> getAnsweredQuestions();
}
A basic definition of a Question type.
interface Question {
int getId();
String getQuestion();
Collection<String> getOptions();
String getUserInput();
void setUserInput(String value);
boolean isUserInputCorrect();
}
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 am naming all of these one by one. Is there a method that takes less space?
public class Matt{
PImage matt,
imgLS1, imgLS2, imgLS3, imgRS1, imgRS2, imgRS3,
imgLSB1, imgLSB2, imgLSB3, imgRSB1, imgRSB2, imgRSB3,
imgLW1, imgLW2, imgLW3, imgRW1, imgRW2, imgRW3,
imgLWB1, imgLWB2, imgLWB3, imgRWB1, imgRWB2, imgRWB3;
public Matt(){
imgLS1 = loadImage("./Images/Matt/MattLS1.png");
imgLS2 = loadImage("./Images/Matt/MattLS2.png");
imgLS3 = loadImage("./Images/Matt/MattLS3.png");
imgRS1 = loadImage("./Images/Matt/MattRS1.png");
imgRS2 = loadImage("./Images/Matt/MattRS2.png");
imgRS3 = loadImage("./Images/Matt/MattRS3.png");
imgLSB1 = loadImage("./Images/Matt/MattLSB1.png");
imgLSB2 = loadImage("./Images/Matt/MattLSB2.png");
imgLSB3 = loadImage("./Images/Matt/MattLSB3.png");
imgRSB1 = loadImage("./Images/Matt/MattRSB1.png");
imgRSB2 = loadImage("./Images/Matt/MattRSB2.png");
imgRSB3 = loadImage("./Images/Matt/MattRSB3.png");
imgLW1 = loadImage("./Images/Matt/MattLW1.png");
imgLW2 = loadImage("./Images/Matt/MattLW2.png");
imgLW3 = loadImage("./Images/Matt/MattLW3.png");
imgRW1 = loadImage("./Images/Matt/MattRW1.png");
imgRW2 = loadImage("./Images/Matt/MattRW2.png");
imgRW3 = loadImage("./Images/Matt/MattRW3.png");
imgLWB1 = loadImage("./Images/Matt/MattLWB1.png");
imgLWB2 = loadImage("./Images/Matt/MattLWB2.png");
imgLWB3 = loadImage("./Images/Matt/MattLWB3.png");
imgRWB1 = loadImage("./Images/Matt/MattRWB1.png");
imgRWB2 = loadImage("./Images/Matt/MattRWB2.png");
imgRWB3 = loadImage("./Images/Matt/MattRWB3.png");
}
}
Put your images in a Map<String,PImage>, organizing the map by image suffix. As far as accessing the images is concerned, this approach may be slightly less convenient/efficient than using variables directly, but it will save you a lot of space:
static final String[] suffixes = new String[] {"LS1", "LS2", "LS3", ..., "RWB3"};
Map<String,PImage> images = new HashMap<String,PImage>();
public Matt() {
for (String suffix : suffixes) {
PImage image = loadImage("./Images/Matt/Matt"+suffix+".png");
images.put(suffix, image);
}
}
Since the "LS", etc., seem to have semantic meaning, I'd suggest a variation of the solution by #dasblinkenlight that uses an enum:
final int N_FILES = 3; // files/position -- could also be a variable
enum Position {
LS, RS, LSB, RSB, LW, RW, LWB, LRB
}
Map<Position, String[]> files = new EnumMap<>(Position.class);
for (Position pos : Position.values()) {
String[] posFiles = new String[N_FILES];
files.put(pos, posFiles);
for (int i = 1; i <= N_FILES; ++i) {
posFiles[i-1] = "./Images/Matt/Matt" + pos.name() + i + ".png";
}
}
Then you can access any element with code like this:
Position p = RS; // or any other value
int index = 0; // 0..(N_FILES-1), corresponding to suffixes 1..N_FILES
String fileName = files.get(p)[i];
I have a csvfile
id|name
1|PC
2|Activation
3|USB
public class TESTResult
{
private Long id;
private String name;
private Float score;
// with setters & getters
}
public class TEST
{
private Long id;
private String name;
// with setters & getters
}
public class JobTESTTagger {
private static Version VERSION;
private static CharArraySet STOPWORDS;
private static RewriteMethod REWRITEMETHOD;
private static Float MINSCORE = 0.0001F;
static {
BooleanQuery.setMaxClauseCount(100000);
VERSION = Version.LUCENE_44;
STOPWORDS = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
REWRITEMETHOD = MultiTermQuery.CONSTANT_SCORE_FILTER_REWRITE;
}
public static ArrayList<TESTResult> searchText(String text, String keyId,
List<TEST> TESTs) {
ArrayList<TESTResult> results = new ArrayList<TESTResult>();
MemoryIndex index = new MemoryIndex();
EnglishAnalyzer englishAnalyzer = new EnglishAnalyzer(VERSION,STOPWORDS);
QueryParser parser = new QueryParser(VERSION, "text", englishAnalyzer);
parser.setMultiTermRewriteMethod(REWRITEMETHOD);
index.addField("text", text, englishAnalyzer);
for (int i = 0; i < TESTs.size(); i++) {
TEST TEST = TESTs.get(i);
String criteria = "\"" + TEST.getName().trim() + "\"";
if (criteria == null || criteria.isEmpty())
continue;
criteria = criteria.replaceAll("\r", " ");
criteria = criteria.replaceAll("\n", " ");
try {
Query query = parser.parse(criteria);
Float score = index.search(query);
if (score > MINSCORE) {
int result = new TESTResult(TEST.getId(), TEST.getName(),score);
results.add(result);
}
} catch (ParseException e) {
System.out.println("Could not parse article.");
}
}
return results;
}
public static void main(String[] args) {
ArrayList<TESTResult> testresults = searchText(text, keyId, iths);
CsvReader reader = new CsvReader("C:\a.csv");
reader.setDelimiter('|');
reader.readHeaders();
List<TEST> result = new ArrayList<TEST>();
while (reader.readRecord()) {
Long id = Long.valueOf(reader.get("id").trim());
String name = reader.get("name").trim();
TEST concept = new TEST(id, name);
result.add(concept);
}
String text = "These activities are good. I have a good PC in my house.";
}
I am matching 'activities' to Activation. How is it possible. Can anybody tell me how Lucene matches the words.
Thanks
R
EnglishAnalyzer, along with most language-specific analyzers, uses a stemmer. This means that it reduces terms to a stem (or root) of the term, in order to attempt to match more loosely. Mostly this works well, removing suffixes and matching up derived words to a common root. So when I search for "fish", I also find "fished", "fishing" and "fishes".
In this case though, both "activities" and "activation" both reduce to the root of "activ", resulting in the match you are seeing. Another example: "organ", "organic" and "organize" all have the common stem "organ".
You can stem or not, neither approach is perfect. If you don't stem you'll miss relevant results. If you do, you'll hit some odd irrelevant results.
To deal with specific problematic cases, you can define a stemmer exclusion set in EnglishAnalyzer to prevent stemming just on those specific problematic terms. In this case, I would think of "activation" as the probable term to prevent stemming on, though you could go either way. So I could do something like:
CharArraySet stemExclusionSet = new CharArraySet(VERSION, 1, true);
stemExclusionSet.add("activation");
EnglishAnalyzer englishAnalyzer = new EnglishAnalyzer(VERSION, STOPWORDS, stemExclusionSet);
In my program the user declares a string of numbers that I am trying to figure out to turn into an array.
Example:
WeeklyFiber week2 = new WeeklyFiber("CS4567", "11/24/13", 32, "27, 26,
28");
Im trying to figure out how to add that string into my class instance variable.
This is what I have:
private String sampleID;
private String weekOfTest;
private int engineerID;
private String[] strengths = new String[20];
private static int count;
public WeeklyFiber(String sampleID, String weekOfTest, int engineerID, String strengths)
{
this.sampleID = sampleID;
this.weekOfTest = weekOfTest;
this.engineerID = engineerID;
this.strengths = strengths;
count++;
}
My compile error message says incompatible types, required: String[], found: String
It is because you have declared String[] strengths which is an array.
declare your constructor like this :
public WeeklyFiber(String sampleID, String weekOfTest, int engineerID, String[] strengths)
{
this.sampleID = sampleID;
this.weekOfTest = weekOfTest;
this.engineerID = engineerID;
this.strengths = strengths;
count++;
}
Make a call like :
WeeklyFiber week2 = new WeeklyFiber("CS4567", "11/24/13", 32, new String[] {"27","26", "28"});
You need to parse that String of numbers to multiple Strings. For example,
this.strengths = strengths.split(",");
You can't say this.strengths = strengths because the strengths argument is of type String and not String[]. That is where your error is coming from.
Pass it like this:
WeeklyFiber week2 = new WeeklyFiber("CS4567", "11/24/13", 32,
new String[] { "27", "26", "28" });