Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am working on making a dating website on java. I want to find the three most compatible matches for a user. So i have an array of three ints and if a user is more compatible the least compatible score will be replaced. I do this using selection sort. I also need the references to be correct so i Can return the proper names. I can't figure our how to sort the string array. Thanks for the help and heres the code:
public void findMatches(String matchName)
{
String nameA = null;
String nameB = null;
String nameC = null;
int matchA = -1;
int matchB = -2;
int matchC = -3;
Member ref = userList.get(matchName);
if(ref.getDesiredAge()>=45 && ref.getDesiredSex().equalsIgnoreCase("Male"))
{
for(String na : userListMaleOld.keySet())
{
Member refA = userListMaleOld.get(na);
int numberOfMatches=findQuestionMatches(ref, refA);
int [] counts = {matchA, matchB, matchC};
String [] names = {nameA, nameB, nameC};
counts = doSelectionSort(counts);
if(numberOfMatches>counts[0]);
{
counts[0] = numberOfMatches;
?!?!?!?!?!??!??!??!WHAT HERE?!?!
}
Use a Map instead.
Concrete this means that you can do something like this:
Map<User, Integer> bestMatches = new HashMap<>();
void validateUser(User user, int value) {
if(bestMatches.size() < 3) {
bestMatches.put(User, 3);
return;
}
Map<User, Integer> newMap = new HashMap<User, Integer>();
User minValue = Collections.min(bestMatches.values());
if(value > minValue) {
for(Map.Entry<User, Integer> entry: bestMatches.entrySet()) {
if(entry.getValue() != minValue) {
newMap.put(entry.getKey(), entry.getValue());
}
}
newMap.put(user, value);
}
bestMatches = newMap;
}
It's probably not very optimized, but you can fix that as you wish. Basically just check if the value of the current user is higher than the lowest value among the existing users in the collection. If it is, create a new collection with the 2 other users and assign that to your first collection.
For large datasets this would be impractical, but we're talking about 3 users here so it shouldn't be an issue.
If these are actually supposed to be name / score pairs (i.e. scoreA is the score for nameA, scoreB is the score for nameB and so on), then the simple solution is something like this:
public class Score {
private String name;
private int score;
// Declare a constructor and getters
}
... and to use this appropriately. For instance, you could now sort a list or array of these Score objects, by name or by score.
Unfortunately, it is not possible to figure out what the code you've shown us is supposed to do, and how it is supposed interact with the rest of your code. Therefore, it is not entirely clear how you should modify your code to use this. And it maybe that you are best of starting over following Jeroen's advice and completely redesigning your data structures.
Related
I am doing a quiz app, with a lot of questions in different chapters. Every chapter of course is an array.
But now, I have come to the point where I need for one specific chapter to pull ALL the questions and answers from ALL the chapters. So basically its an array within another array/s.
public void shuffleChapterRandomTest() {
shuffledPositionChapterRandomTest = new String[chapterRandomTestQuestions.length];
for (int k = 0; k < shuffledPositionChapterRandomTest.length; k++) {
shuffledPositionChapterRandomTest[k] = String.valueOf(k);
}
Collections.shuffle(Arrays.asList(shuffledPositionChapterRandomTest));
Log.i("TAG", "shuffle: " + shuffledPositionChapterRandomTest[0] + " " + shuffledPositionChapterRandomTest[1]);
}
public static String shuffledPositionChapterRandomTest[];
private String chapterRandomTestQuestions[][] = {
//This are all the chapters being called
Questions,
chapterTwoQuestions,
chapterThreeQuestions,
chapterFourQuestions,
chapterFiveQuestions,
chapterSixQuestions,
chapterSevenQuestions,
chapterEightQuestions,
chapterNineQuestions,
chapterTenQuestions,
chapterElevenQuestions,
chapterTwelveQuestions,
chapter13Questions,
chapter14Questions
};
//This is my get method
public String[] getChapterRandomTestQuestion(String a) {
return chapterRandomTestQuestions[Integer.parseInt(a)];
}
When I try to pull the string from "questions" as setText for the TextView.
private void updateQuestion() {
if (questionnumber < questionBank.getChapterRandomTestLength()) {
storeUserData.setInt(Constants.TOTAL_QUESTION,questionBank.getChapterRandomTestLength());
binding.tvCountQuestion.setText(questionnumber+1+"/"+questionBank.getChapterRandomTestLength());
binding.tvQuestion.setText(questionBank.getChapterRandomTestQuestion(shuffledPositionChapterRandomTest[questionnumber]));
binding.tvAnsOne.setText(questionBank.getChapterRandomTestChoice(shuffledPositionChapterRandomTest[questionnumber], 1));
binding.tvAnsTwo.setText(questionBank.getChapterRandomTestChoice(shuffledPositionChapterRandomTest[questionnumber], 2));
binding.tvAnsTnree.setText(questionBank.getChapterRandomTestChoice(shuffledPositionChapterRandomTest[questionnumber], 3));
answer = questionBank.getChapterRandomTestCorrectAnswer(shuffledPositionChapterRandomTest[questionnumber]);
questionnumber++;
It shows an error:
Required: Java.lang.String
Found: Java.lang.String[]
How can I pull the questions and answers as Strings and not as arrays. Thank you!
When you call
questionBank.getChapterRandomTestQuestion(shuffledPositionChapterRandomTest[questionnumber])
You're retrieving a String[], representing one of the entries in chapterRandomTestQuestions. You need to use
questionBank.getChapterRandomTestQuestion(shuffledPositionChapterRandomTest[questionnumber])[someNumber]
Also, I notice you're filling shuffledPositionChapterRandomTest with String representations of Integers. Why not make that an int[] instead, and avoid having to cast to String and then back to int?
And another note/question: I think you may have written the wrong thing for your arrays. The syntax is
SomeObject[] variable
not
SomeObject variable[]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have an Object Collection with 5 fields:
id;
entityType;
entityId;
brandId;
productId;
To sort an ArrayList of Collection I have written the following Comparaor.
Comparator<Collection> collectionComparator = new Comparator<Collection>() {
#Override
public int compare(Collection collection1, Collection collection2) {
if(collection1.getId().equals(collection2.getId())) {
if(collection1.getEntityType().equals(collection2.getEntityType())) {
if(collection1.getEntityId().equals(collection2.getEntityId())) {
if(collection1.getBrandId().equals(collection2.getBrandId())) {
return collection1.getProductId().compareTo(collection2.getProductId());
} else {
return collection1.getBrandId().compareTo(collection2.getBrandId());
}
} else {
return collection1.getEntityId().compareTo(collection2.getEntityId());
}
} else {
return collection1.getEntityType().compareTo(collection2.getEntityType());
}
}
return collection1.getId().compareTo(collection2.getId());
}
};
Is this the right way to implement Comparator on the object which has multiple fields to compare?
Your method might be correct, but it is inefficient (unnecessarily calls equals) and difficult to read. It could be rewritten something like this:
public int compare(Collection c1, Collection c2)
{
int n;
n = c1.id.compareTo(c2.id);
if (n != 0) return n;
n = c1.entityType.compareTo(c2.entityType);
if (n != 0) return n;
n = c1.brandId.compareTo(c2.brandId);
if (n != 0) return n;
return c1.productId.compareTo(c2.productId);
}
Even better is to use a library method which abstracts all this logic away so you don't have to think about it. E.g. using apache.commons.lang CompareToBuilder
public int compare(Collection c1, Collection c2)
{
return new CompareToBuilder()
.append(c1.id, c2.id)
.append(c1.entityType, c2.entityType)
.append(c1.brandId, c2.brandId)
.append(c1.productId, c2.productId)
.toComparison();
}
First, Collection is a class from java.util package, so it's probably not the best idea to name your own class Collection too, although it is certainly possible.
Second, JDK8 have some neat ways to create comparators, check here: jdk8 comparators
Esspecially section 6 and 9.
EDIT: Without JKD8:
When comparing by 5 different attributes, I wouldn't hardcode the comparasion like that, you can always create your own comparator chainer (something like point 9 from previous link) and chain 5 separate comparators together.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
Why don't I get 20 after delivering e.g. "Obsidian" to Test(String pStr) if I call getMatInt() ?
Also tried .toString() after all String-declariations, also declarated e.g. "Obsidian" as new String a. Nothing works.
getBonus is aways returning a 0 instead of a 20/30/... .
I already tried "Obsidian" and "obsidian", both doesnt work for me ...
public class test
{
private String str;
private int matInt;
private int bonus;
private int magic;
public test(int pMagic, String pStr)
{
int magic = pMagic;
str = pStr;
}
private void materialEquals()
{
if(str.equals("Obsidian"))
{
matInt = 20;
}
.....
}
private void calcBonus()
{
materialEquals();
bonus = magic * matInt;
}
public int getBonus()
{
calcBonus();
return bonus;
}
}
try:
public int getMatInt()
{
materialEquals();
return matInt;
}
There is no reason for this in your constructor: str = new String(pStr);, just use str = pStr.
In fact, you might be better off setting matInt in your constructor:
public test(String pStr)
{
str = pStr;
materialEquals();
}
And depending on how many materials you have, you might want to look into using enumeration.
Ok after your edits:
public int getBonus()
{
calcBonus(); //bonus won't be calculated otherwise
return bonus;
}
After further edits:
Your constructor is wrong, you're not initializing int magic. Try this constructor instead.
public test(int pMagic, String pStr)
{
this.magic = pMagic; //int magic = pMagic was a new variable only in the constructor scope
this.str = pStr;
calcBonus();
}
Also you might as well calculate the bonus on construction.
You will need to call materialEquals() so that 20 can be assigned to matInt upon equals comparison, as integers are always initialized to default value 0 upon declaration.
I am creating an array of customer accounts for a company called "customers". I have a method called getGasAccount which will count the number of accounts in the array.
I declared variables in the program class as:
final int MAXACCOUNTS = 10;
int intNUmber, intSelectAccount;
I set up the accounts using:
if (GasAccount.getGasAccount() < MAXACCOUNTS) {
intSelectAccount = GasAccount.getBankAccount()++;
customers[intSelectAccount] = new GasAccount();
}
I want to be able to search for a customer by their account number which is manually input when the constructor is called. I don't want to search by the intSelectAcocunt/array reference.
If I have a method called displayAccountDetails, is there another way of finding the account rather than using:
customers[intSelectAccount].displayAccountDetails();
Implement equals method in GasAccount like this
public boolean equals(Object objToCompare){
if (objToCompare != null){
return objToCompare instanceof GasAccount && ((GasAccount)objToCompare).getAccountNumber() == getAccountNumber();
}else{
return false;
}
}
Now to find the location of GasAccount object in the array and to display the account details:
java.util.List<GasAccount> gasAccountsList = (java.util.List<GasAccount>)java.util.Arrays.asList(customers);
int objectIndex = gasAccountsList.indexOf([Gas Account Object]);
if (objectIndex != -1){
gasAccountsList.get(objectIndex).displayAccountDetails();
}
Another simple approach suggested by jahroy to search by account number is :
public void getAccountDetails(int accountNumber){
java.util.List<GasAccount> gasAccountsList = (java.util.List<GasAccount>)java.util.Arrays.asList(customers);
for(GasAccount gasAccountObj : gasAccountsList){
if(gasAccountObj.getAccountNumber() == accountNumber){
gasAccountObj.displayAccountDetails();
break;
}
}
}
OR
public void getAccountDetails(int accountNumber){
for(GasAccount gasAccountObj : customers){
if(gasAccountObj.getAccountNumber() == accountNumber){
gasAccountObj.displayAccountDetails();
break;
}
}
}
The data structure that you want is a HashMap. You can do something like this.
public class AccountClass{
//You can fill in the details. I sounds like you know about constructors
//getters, setters, etc.
private HashMap<String, String> accountHash = new HashMap<String, String>();
public HashMap<String, String> getHashMap()
{
return this.accountHash;
}
}
when you want to look up an account by account number, you will be able to do something like this.
AccountClass acct = new AccountClass();
acct.getHashMap().get("1234");
assuming that you have actually put an entry with account number "1234" in your map it will return the value associated with that key.
Here is the Wikipedia article if you want to do more reading.
Edit: I have a few more things to add based on some comments.
It might be better if you made the HashMap static like this
private static HashMap<String, String> accountHash = new HashMap<String, String>();
When you declare the variable static this makes it so that you don't have to instantiate an object to access the HashMap. You can just do something like this.
AccountClass.accountHash.get();
or
AccountClass.accountHash.put();
If you want to add things to your HashMap, you need to use the put method. Here is an example.
accountHash.put("1234","My test account").
Now when you use this,
accountHash.get("1234");//you will get My test account
you will get the value associated with the "1234" key.
Keep in mind this example is just to give you an idea about how to use it. You can have a map of , , or whatever else you want.
The error i am having here is a infinite or near infinite loop in my method calls and class's creating other class's constructors. What my program is trying to do is semi-randomly generate survey results based off actual statistics. I would highly appreciate not only some insight in whats going wrong here. But some advice and pointers on how to prevent this from happening and ways to analyze the error messages by myself. I get how some of the work but like i stated below i am new to programming im a freshman in college so programming is new to me. Thanks in advance and sorry for my previous post, thought i would take the time to give you guys an appropriate one.
Im new to programming this is my 2nd project ive done on my own so im sorry if its not the best.
This is my Test class:
public Tester()
{
randomGenerator = new Random();
probability = new Probability();
stats = new Statistics();
double chance = randomGenerator.nextDouble();
double gender = probability.getProbabilityOfMale();
if(chance > gender)
{
male = false;
stats.incrementFemale();
}else{
male = true;
stats.incrementMale();
}
age = randomGenerator.nextInt(49)+16;
int range = stats.getNumberOfQuestion();
for(int i=0;i<range;i++)
{
probabilities = probability.probOfAnswer(i);
answers = probability.getAnswers(i);
chance = randomGenerator.nextDouble();
int size = probabilities.size();
for(int j=0;j<size;j++)
{
double qTemp = chance - probabilities.get(j);
if(qTemp <= 0.0)
{
Answer aTemp = answers.get(j);
aTemp.incrementCounter();
answers.set(j,aTemp);
}
}
}
}
Statistics class:
public ArrayList<Answer> getAnswers(int index)
{
temp = survey.getAnswers(index);
return temp;
}
public int getMale()
{
return male;
}
public int getFemale()
{
return female;
}
public int getNumberOfQuestion()
{
return numberOfQuestion;
}
public void incrementNumberOfQuestion()
{
numberOfQuestion++;
}
public void incrementMale()
{
male++;
}
public void incrementFemale()
{
female++;
}
and probability class:
public Probability()
{
stats = new Statistics();
probOfAnswer = new ArrayList<Double>(0);
}
public ArrayList<Double> probOfAnswer(int index)
{
temp = stats.getAnswers(index);
int size = temp.size();
for(int i=0;i<size;i++)
{
aTemp = temp.get(i);
for(int j=0;j<size;j++)
{
Answer aTemp = temp.get(j);
sum += (double)aTemp.getCounter();
}
double number = (double)aTemp.getCounter();
probOfAnswer.add(number/sum);
sum = 0;
}
return probOfAnswer;
}
public ArrayList<Answer> getAnswers(int index)
{
temp = stats.getAnswers(index);
return temp;
}
public ArrayList<Double> getProbofAnswer()
{
return probOfAnswer;
}
public void probabilityOfMale()
{
double male = (double)stats.getMale();
double female = (double)stats.getFemale();
probabilityOfMale = male / (male + female);
}
public double getProbabilityOfMale()
{
return probabilityOfMale;
}
These are the only real important parts where the loop exsists the rest of the code is not needed to be uploaded.
Im having difficulty uploading my error message on this site its not accepting it as code in the code insert, then it wont let me submit the message afterwards so im going to upload the code elseware and link it.
http://forum.overdosed.net/index.php/topic/56608-this-is-unimportant/
But i dont know how long that forum will let me keep that post there ><
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Probability.<init>(Probability.java:19)
You need to check why Question is creating Statistics object and again Statistics is trying to create Question object leading to infinite recursion. As the line numbers are given you can take a look at corresponding lines.
Judging by the stack trace, the problem lies in three parts which you haven't shown us - the Question and Statistics constructors and the Survey.addQuestion method:
From the stack trace:
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
at Survey.addQuestion(Survey.java:23)
at Statistics.<init>(Statistics.java:52)
at Question.<init>(Question.java:17)
So your Question constructor is calling the Statistics constructor. But the Statistics constructor is then calling Survey.addQuestion, which is in turn calling the Question constructor.
It feels to me like there's much more construction going on than is really useful. Why would a Statistics constructor need to add anything to a survey? I wouldn't expect a Statistics class to even know about surveys and questions.
It's entirely possible that a lot of this can be fixed by passing a reference to an existing object to the constructors - so the Probability constructor may be better taking a Statistics reference in its constructor and using that for its stats field than creating a new Statistics object itself. It's hard to say without knowing what these classes are really meant to represent though... which may be part of the problem. Do you have a firm grasp of what the responsibility of each class is? Think about that carefully before making any code changes.
We don't have the relevant source code, but the error message says what's wrong:
Tester creates a Probability
Probability constructor creates a Statistics
Statistics constructor calls Survey.addQuestion()
addQuestion() creates a Question
Question creates a Statistics (goto 3 and loop infinitely)
I think you should probably pass objects around rather than creating them each time.