"Duplicate" entries in ArrayList? - java

i have this class thats going to fill a list with All employees that are pre made in an array. I can populate an ArrayList with employees but the only problem is that i get a few "Duplicate" entries, i use quotes cause they are not EXACTLY the same but they could share the same name or employee number but may not have the same hire year or salary ect.
heres the employee class :
public class Employee {
public String EmployeeName;
public String EmployeeNumber;
public int hireyear;
public double WeeklyEarning;
public Employee()
{
EmployeeName = null;
EmployeeNumber = null;
hireyear = 0;
WeeklyEarning = 0;
}
public static final String[] Empnum = new String[] {
"0001-A", "0002-B","0003-C","0004-D","0002-A",
"0003-B","0004-C","0005-D","0011-A", "0012-B",
"0013-C","0014-D","0121-A", "0122-B","0123-C",
"0321-A", "0312-B","1234-D","4321-C","1122-D"};
public static final String[] Ename = new String[] {
"Josh", "Alex", "Paul", "Jimmy", "Josh", "Gordan", "Neil", "Bob",
"Shiv", "James", "Jay", "Chris", "Michael", "Andrew", "Stuart",
"Dave","Benjamin","Dan","Brian","Michelle"};
public String getEmployeeName()
{
return this.EmployeeName;
}
public String getEmployeeNumber()
{
return this.EmployeeNumber;
}
public int gethireyear()
{
return this.hireyear;
}
public double getWeeklyEarning()
{
return this.WeeklyEarning;
}
public String setEmployeeName(String EName)
{
return this.EmployeeName = EName;
}
public String setEmployeeNumber(String ENumber)
{
return this.EmployeeNumber = ENumber;
}
public int setEmployeehireyear(int Ehireyear)
{
return this.hireyear = Ehireyear;
}
public double setEmployeeweeklyearning(double Eweeklyearning)
{
return this.WeeklyEarning = Eweeklyearning;
}
public String toString(){
String data = "\n Employee Name : " + EmployeeName + " \n Employee Number: " + EmployeeNumber + " \n Hire Year : " + hireyear + "\n Weekly Earnings : " + WeeklyEarning;
return data;
}
public boolean equals(Object o){
if(this == null){
return false;
}
if(this == o){
return true;
}
if(!(o instanceof Employee)){
return false;
}
Employee temp = (Employee) o;
if(this.getEmployeeName().equals(temp.getEmployeeName())){
return true;
}
if(this.getEmployeeNumber().equals(temp.getEmployeeNumber())){
return true;
}
if(this.gethireyear() == temp.gethireyear()){
return true;
}
if(this.getWeeklyEarning() == temp.getWeeklyEarning()){
return true;
}
return false;
}
}
Heres the generateList method that will populate the list:
public ArrayList<Employee> generateEmpList(){
empList = new ArrayList <Employee>();
Random empPicker = new Random();
for(int i = 0; i < 20; i++){
int id = empPicker.nextInt(20);
if(id < 12) // roll for production worker
{
//System.out.println("Adding Production Worker");
ProductionWorker temp = new ProductionWorker();
temp = temp.generateProductionWorker();
prodWorker = temp;
empList.add(prodWorker);
}
else //roll for Shift supervisor
{
//System.out.println("Adding Shift supervisor");
ShiftSupervisor supervisor = new ShiftSupervisor();
supervisor = supervisor.generateShiftSupervisor();
shiftWorker = supervisor;
empList.add(shiftWorker);
}
}
Iterator iterator = empList.iterator();
while (iterator.hasNext()) {
System.out.println("");
System.out.println(iterator.next());
}
return empList;
}
and also which could be helpful is the "generateProductionWorker()" and shiftSupervisor methods - to keep it short ill only post prod worker method cause they are basically the same:
public ProductionWorker generateProductionWorker(){
Random rng = new Random();
int numberOfEmployeeNames = Ename.length;
ProductionWorker tempPworker = new ProductionWorker();
String employeeName = Ename[rng.nextInt(numberOfEmployeeNames)];
tempPworker.setEmployeeName(employeeName);
int numberOfEmployeeNumbers = Empnum.length;
String employeeNumber = Empnum[rng.nextInt(numberOfEmployeeNumbers)];
tempPworker.setEmployeeNumber(employeeNumber);
int yearHired = rng.nextInt(35) + 1980;
tempPworker.setEmployeehireyear(yearHired);
double weeklySalary = rng.nextInt((100) * 100);
tempPworker.setEmployeeweeklyearning(weeklySalary);
int hourlyRate = rng.nextInt(20) + 10;
tempPworker.setHourlyRate(hourlyRate);
return tempPworker;
}
I'm sure I'm missing something trivial but any ideas why i get similar entries when i have a list of 20 names and numbers?
ex:
empname - josh
empnum - 0000-A
hireyear - 1994
salary - 40,000
empname - josh
empnum - 0000-A
hireyear - 1999
salary - 60,500
any advice would help, Thanks!

Look at the equals method in your Employee class. If their name are the same, you return true, which means these are equals. The same is for the other attributes. You must replace your if statements.

I agree with Georgi, you equals method is the culprit.
Currently it is returning true after the first if statement at the line that reads
if(this.getEmployeeName().equals(temp.getEmployeeName())){
return true;
}
Because it is a return statement it stops the method from continuing to the other statements. You might try this:
public boolean equals(Object o){
if(this == null){
return false;
}
if(this == o){
return true;
}
if(!(o instanceof Employee)){
return false;
}
//set all the elements in the array to false and change to true when true.
boolean [] doesItMatch = new boolean[4];
doesItMatch[0] = false;
doesItMatch[1] = false;
doesItMatch[2] = false;
doesItMatch[3] = false;
Employee temp = (Employee) o;
if(this.getEmployeeName().equals(temp.getEmployeeName())){
doesItMatch[0] = true;
}
if(this.getEmployeeNumber().equals(temp.getEmployeeNumber())){
doesItMatch[1] = true;
}
if(this.gethireyear() == temp.gethireyear()){
doesItMatch[2] = true;
}
if(this.getWeeklyEarning() == temp.getWeeklyEarning()){
doesItMatch[3] = true;
}
int check = 0;
//Now that you have checked all the values, check the array. Using a simple counter.
for(int i = 0; i < doesItMatch.length; i++){
if(doesItMatch[i]){
check++;
} else {
check--;
}
}
//The counter should be 4 when the if statements above are all true. Anything else is false.
if(check == 4){
return true;
} else {
return false;
}
}
This method now checks each of the attributes in the Employee class. (Name, Number, Hire year and so on. If you create more attributes to the class it is easy to add more elements to the array just be sure to set them to false.)
Hope this helps
This also would take a little maintenance if you expanded the Employee class so you might want to find a way to make it a little easier on yourself.

Related

Method that doesn't allow more participants than the maximum and same number of registration

I have a issue here. I need to create this method:
Method: registraParticipante (Aluno alu) that will receive by parameter one
student(Aluno) and add to the participant(participante) array. The method should also implement the following rules:
control not to allow more participants to register which was defined in the attribute: Maximum number of participants(qtMaxParticipantes);
not allow registration of a participant who has the same number of registration(int matricula) of an already registered participant.
I have the superclass Usuario (means User) with the int matricula in it
and the subclass Aluno (means student)
PROBLEM SOLVED - Thanks Andre.
public void registraParticipante(Aluno alu) {
if (!matriculaJaExistente(alu))
{
for (int i = 0; i < listaDeParticipantes.length; i++)
{
if (listaDeParticipantes[i] == null)
{
listaDeParticipantes[i] = alu;
break;
} else {
System.out.println("Número maximo de participante atingido.");
}
}
} else {
System.out.println("Aluno já matriculado.");
}
}
public boolean matriculaJaExistente(Aluno a)
{
boolean resultado = false;
for (int i = 0; i < listaDeParticipantes.length; i++)
{if (listaDeParticipantes[i].getMatricula() == a.getMatricula())
{
resultado = true;
}
else
{
resultado = false;
}
}
return resultado ;
}
I don't know if you necessarily have to use an array, so I guess that using a List would be the best solution, than, your code would look like this:
List<Aluno> alunosList = new ArrayList();
private int maxParticipantes = 5; // arbitrary number
public void registraParticipante(Aluno a) {
if (alunosList.size() > maxParticipantes || alunoJaRegistrado(a)) {
System.out.println("Can't add this aluno");
} else {
alunosList.add(a);
}
}
public boolean alunoJaRegistrado(Aluno aluno) {
boolean result;
for (Aluno a : alunosList) { // this goes through each aluno on the list
if (a.getMatricula() == aluno.getMatricula) {
result = true;
break;
} else result = false;
}
return result;
}

Converting multiple strings into one

I'm trying to convert multiple strings into one simple dialogue from a NPC. Basically what I'm trying to do is make a list of all the skills a player has 200M experience in and output it into a NPC dialogue.
OLD
if (componentId == OPTION_4) {
sendNPCDialogue(npcId, 9827, "You can prestige: "+maxedSkills()+"");
}
private String maxedSkills() {
return ""+attackMax()+""+strengthMax()+""+defenceMax()+"";
}
public String attackMax() {
if (player.getSkills().getXp(Skills.ATTACK) == 200000000)
return "Attack, ";
else
return "";
}
public String strengthMax() {
if (player.getSkills().getXp(Skills.STRENGTH) == 200000000)
return "Strength, ";
else
return "";
}
public String defenceMax() {
if (player.getSkills().getXp(Skills.DEFENCE) == 200000000)
return "Defence, ";
else
return "";
}
With that code I have it working, but that is a lot of code to add due to there being 25 different skills. How would I create a way to make all of the skills be referenced into one? Here are all of the skill names:
public static final String[] SKILL_NAME = { "Attack", "Defence", "Strength", "Constitution", "Ranged", "Prayer",
"Magic", "Cooking", "Woodcutting", "Fletching", "Fishing", "Firemaking", "Crafting", "Smithing", "Mining",
"Herblore", "Agility", "Thieving", "Slayer", "Farming", "Runecrafting", "Hunter", "Construction",
"Summoning", "Dungeoneering" };
New and working (for attack/strength/defence):
public static final int[] SKILL_TYPE = {Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE};
public String maxedSkills() {
StringBuffer sb = new StringBuffer();
for(int i = 0; i < SKILL_TYPE.length; i++) {
if (player.getSkills().getXp(i) == 200000000) {
if(sb.length()>0) sb.append(", ");
sb.append(Skills.SKILL_NAME[i]);
}
}
if(sb.length()>0) sb.append(".");
return sb.toString();
}
Simplest way would be to have a parameteried method that takes the Skill type as input. Here is how it would look like:
public String skillMax(Skills skill) {
if (player.getSkills().getXp(skill) == 200000000)
return skill.getName() + ", ";
else
return "";
}
The next thing to do is to provide a name to the skill in Skills enum. Something like this should work:
public enum Skills {
DEFENSE("Defense"), ...;
private String name;
Skills(String name) { this.name = name; }
String getName() { return this.name; }
}
Use a StringBuffer (thread safe) or a StringBuilder and do something like this.
....
public static final Skills[] SKILL_TYPE = {Skills.Attack, Skills.Defence, ...};
public String getBigString() {
StringBuffer sb = new StringBuffer();
int nSkills = 0, lSkill = 0;
for( int i = 0; i < SKILL_TYPE.length; i++ )
{
if( player.getSkills().getXp(SKILL_TYPE[i]) == K_SOMELEVEL ) {
if(nSkills > 0) sb.append(", ");
lSkill = sb.length(); // track position of last skill in string
nSkills += 1;
sb.append(SKILL_NAME[i]);
}
}
if( nSkills > 0 )
{
if( nSkills > 1 ) sb.insert( lSkill, "and ");
sb.append(".");
}
return sb.toString();
}

Compare RDD Objects - Apache Spark

I'm fairly new into the apache spark technology and I'm having some problems while trying to analyze data I'm pulling from my files.
I have big list of genes information, and I'm pulling that information to a RDD, so far so good.
JavaRDD<Gene> inputfile = sc.textFile(logFile).map(
new Function<String, Gene>() {
#Override
public Gene call(String line) throws Exception {
String[] values = line.split("\t");
Gene gen = null;
//We are only interested in genes;
if( values.length > 2 && values[2].equalsIgnoreCase("gene") && !line.contains("#")){
String[] infoGene = values[8].split(";");
String geneId = StringUtils.substringBetween(infoGene[0], "\"");
String geneType = StringUtils.substringBetween(infoGene[2], "\"");
String geneName = StringUtils.substringBetween(infoGene[4], "\"");
gen = new Gene(geneName,values[3],values[4]);
return gen;
}
return gen;
}
}
).filter(new Function<Gene, Boolean>() {
#Override
public Boolean call(Gene gene) throws Exception {
if(gene == null)
return false;
else
return true;
}
});
The Gene class:
public class Gene implements Serializable{
String firstBp;
String lastBp;
String name;
public Gene(String name, String firstBp, String lastBp) {
this.name = name;
this.firstBp = firstBp;
this.lastBp = lastBp;
}
public String getFirstBp() {
return firstBp;
}
public String getLastBp() {
return lastBp;
}
public String getName() {
return name;
}
public String toString(){
return name + " " + firstBp + " " + lastBp;
}}
The problem starts here, I need to analyze if 2 Genes overlay, and for that I've made this simple utility function:
public static Boolean isOverlay(Gene gene1, Gene gene2){
int gene1First = Integer.parseInt(gene1.getFirstBp());
int gene1Last = Integer.parseInt(gene1.getLastBp());
int gene2First = Integer.parseInt(gene2.getFirstBp());
int gene2Last = Integer.parseInt(gene2.getLastBp());
if(gene2First >= gene1First && gene2First <= gene1Last) // FirstBp - Gene2 inside
return true;
else if (gene2Last >= gene1First && gene2Last <= gene1Last) // LastBP - Gene2 inside
return true;
else if (gene1First >= gene2First && gene1First <= gene2Last) // FirstBp - Gene1 inside
return true;
else if (gene1Last >= gene2First && gene1Last <= gene2Last) // LastBP - Gene1 inside
return true;
else
return false;
}
Now what I'm doing and I think is wrong is transforming the RDD Object into a list by doing:
List<Gene> genesList = inputfile.collect();
And iterate over that list to check if there are overlays and save to the file the results which is taking ages because I'm not using spark.
List<OverlayPair> overlayPairList= new ArrayList<OverlayPair>();
List<String> visitedGenes = new ArrayList<String>();
for (Gene gene1 : genesList){
for (Gene gene2 : genesList) {
if (gene1.getName().equalsIgnoreCase(gene2.getName()) || visitedGenes.contains(gene2.getName())) {
continue;
}
if (isOverlay(gene1, gene2))
overlayPairList.add(new OverlayPair(gene1.getName(), gene2.getName()));
}
visitedGenes.add(gene1.getName());
}
JavaRDD<OverlayPair> overlayFile = sc.parallelize(overlayPairList);
//Export the results to the file
String outputDirectory = "/Users/joaoalmeida/Desktop/Dissertacao/sol/data/mitocondrias/feup-pp/project/data/output/overlays";
overlayFile.coalesce(1).saveAsTextFile(outputDirectory);
The Overlay pair is basically an object with the 2 genes name.
Is there anyway to do this 2nd part while taking advantage of spark? Because the time complexity of those 2 for's its to big for the amount of data I currently have.
Yes, there is, you have to use RDD.cartesian function to get all the pairs and then you can basically apply the function you wrote.

Get random object from arraylist specific variable

I'm trying to get a random object from an arraylist. The random should be among the object in the arraylist having the variable available as true.
Right now it get a random attendant from the whole arraylist. I just need it to specify a limit to attendants being true(variable)
this is the line:
return myAtt.get(randAtt.nextInt(myAtt.size()));
This is the method:
public static Attendant askForAtt() {
Scanner scanAtt = new Scanner(System.in);
Random randAtt = new Random();
//Attendant asnAtt = null;
System.out.println("Do you require an Attendant ? Y or N");
String response = scanAtt.next();
if ((response.equals("y")) || (response.equals("yes")) || (response.equals("Yes")) || (response.equals("Y"))) {
// Cars.setAssignedTo(myAtt.get(randAtt.nextInt(myAtt.size())));
return myAtt.get(randAtt.nextInt(myAtt.size()));
} else if ((response.equals("n")) || (response.equals("no")) || (response.equals("No")) || (response.equals("N"))) {
return new Attendant ("User");
}
return new Attendant ("User"); //If input is neither Yes nor No then return new Attendant
}
What am I supposed to type?
My attendants are like that:
public Attendant(int staffNum, String id, boolean available, attNm name, Cars assign) {
this.staffNum = staffNum;
this.id = id;
this.available = available;
this.name = name;
this.assign = assign;
}
PS:Sorry for my English. It's my 3rd language
On your Attendant class, add this function
public boolean isAvailable(){
return available;
}
Then
public static Attendant askForAtt() {
...
if ((response.equals("y")) || (response.equals("yes")) || (response.equals("Yes")) || (response.equals("Y")) && someoneIsAvailable()) {
ArrayList<Attendant> temp = getAvailableAttendants();
Attendant attendant = temp.get(randAtt.nextInt(temp.size()));
return attendant;
}
...
}
public boolean someoneIsAvailable(){
for(int i = 0; i<myAtt.size(); i++){
if(myAtt.get(i).isAvailable()){
return true;
}
}
return false;
}
public ArrayList<Attendant> getAvailableAttendants(){
ArrayList<Attendant> availableAtt = new ArrayList<>();
for(int i = 0; i<myAtt.size(); i++){
Attendant att = myAtt.get(i)
if(att.isAvailable()){
availableAtt.add(att);
}
}
return availableAtt;
}
Also, you can use
String.equalsIgnoreCase(String);
cause in your trapping the user could do "yEs". Hope that helps. Tell me if something is wrong

Infinite while loop in java, not reading in sentinel

I've had this problem throughout multiple programs, but I can't remember how I fixed it last time. In the second while loop in my body, the second sentinel value is never read in for some reason. I've been trying to fix it for a while now, thought I might see if anyone had any clue.
import java.text.DecimalFormat; // imports the decimal format
public class Car {
// Makes three instance variables.
private String make;
private int year;
private double price;
// Makes the an object that formats doubles.
public static DecimalFormat twoDecPl = new DecimalFormat("$0.00");
// Constructor that assigns the instance variables
// to the values that the user made.
public Car(String carMake,int carYear, double carPrice)
{
make = carMake;
year = carYear;
price = carPrice;
}
// Retrieves variable make.
public String getMake()
{
return make;
}
// Retrieves variable year.
public int getYear()
{
return year;
}
// Retrieves variable price.
public double getPrice()
{
return price;
}
// Checks if two objects are equal.
public boolean equals(Car c1, Car c2)
{
boolean b = false;
if(c1.getMake().equals(c2.getMake()) && c1.getPrice() == c2.getPrice() &&
c1.getYear() == c2.getYear())
{
b = true;
return b;
}
else
{
return b;
}
}
// Turns the object into a readable string.
public String toString()
{
return "Description of car:" +
"\n Make : " + make +
"\n Year : " + year +
"\n Price: " + twoDecPl.format(price);
}
}
import java.util.Scanner; // imports a scanner
public class CarSearch {
public static void main(String[] args)
{
// initializes all variables
Scanner scan = new Scanner(System.in);
final int SIZE_ARR = 30;
Car[] carArr = new Car[SIZE_ARR];
final String SENT = "EndDatabase";
String carMake = "";
int carYear = 0;
double carPrice = 0;
int count = 0;
int pos = 0;
final String SECSENT = "EndSearchKeys";
final boolean DEBUG_SW = true;
// Loop that goes through the first list of values.
// It then stores the values in an array, then uses the
// values to make an object.
while(scan.hasNext())
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car car1 = new Car(carMake, carYear, carPrice);
carArr[count] = car1;
count++;
}
// Calls the method debugSwitch to show the debug information.
debugSwitch(carArr, DEBUG_SW, count);
// Calls the method printData to print the database.
printData(carArr, count);
// Loops through the second group of values and stores them in key.
// Then, it searches for a match in the database.
**while(scan.hasNext())**
{
if(scan.hasNext())
{
carMake = scan.next();
}
else
{
System.out.println("ERROR - not a String");
System.exit(0);
}
if(carMake.equals(SECSENT))
{
break;
}
if(scan.hasNextInt())
{
carYear = scan.nextInt();
}
else
{
System.out.println("ERROR - not an int" + count);
System.exit(0);
}
if(scan.hasNextDouble())
{
carPrice = scan.nextDouble();
}
else
{
System.out.println("ERROR - not a double");
System.exit(0);
}
Car key = new Car(carMake, carYear, carPrice);
// Stores the output of seqSearch in pos.
// If the debug switch is on, then it prints these statements.
if(DEBUG_SW == true)
{
System.out.println("Search, make = " + key.getMake());
System.out.println("Search, year = " + key.getYear());
System.out.println("Search, price = " + key.getPrice());
}
System.out.println("key =");
System.out.println(key);
pos = seqSearch(carArr, count, key);
if(pos != -1)
{
System.out.println("This vehicle was found at index = " + pos);
}
else
{
System.out.println("This vehicle was not found in the database.");
}
}
}
// This method prints the database of cars.
private static void printData(Car[] carArr, int count)
{
for(int i = 0; i < count; i++)
{
System.out.println("Description of car:");
System.out.println(carArr[i]);
}
}
// Searches for a match in the database.
private static int seqSearch(Car[] carArr, int count, Car key)
{
for(int i = 0; i < count; i++)
{
boolean b = key.equals(key, carArr[i]);
if(b == true)
{
return i;
}
}
return -1;
}
// Prints debug statements if DEBUG_SW is set to true.
public static void debugSwitch(Car[] carArr, boolean DEBUG_SW, int count)
{
if(DEBUG_SW == true)
{
for(int i = 0; i < count; i++)
{
System.out.println("DB make = " + carArr[i].getMake());
System.out.println("DB year = " + carArr[i].getYear());
System.out.println("DB price = " + carArr[i].getPrice());
}
}
}
}
I think this is your problem, but I might be wrong:
Inside your while loop, you have these calls:
next()
nextInt()
nextDouble()
The problem is that the last call (nextDouble), will not eat the newline. So to fix this issue, you should add an extra nextLine() call at the end of the two loops.
What happens is that the next time you call next(), it will return the newline, instead of the CarMake-thing.

Categories