I'm trying to sort courses and organize them by course number.
I have created an array of objects which contain 3 attributes (department, num, title). I want to sort this array by 'num' using the selection sort method. When i try to swap the two arrays the compiler says int cannot be converted to Course[].
public static void sortByNumber(Course[] arr){
int size = arr.length;
for (int i = 0; i < size - 1; i++) {
int min = i;
for (int j = i + 1; j < size; j++) {
if (arr[j].getNum() < arr[min].getNum()) {
min = j;
}
}
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
this is my other class.
public class Course {
//INSTANCE VARIABLES
private String dept = "";
private int num = 0;
private String title = "";
//CONSTRUCTORS
public Course(String dept, int num) {
this.dept = dept;
this.num = num;
}
public Course(String dept, int num, String title) {
this.dept = dept;
this.num = num;
this.title = title;
}
public Course() {
this.dept = "AAA";
this.num = 100;
this.title = "A course";
}
//SETTER AND GETTER METHODS
public void setDept(String dept) {
this.dept = dept;
}
public void setNum(int num) {
this.num = num;
}
public void setTitle(String title) {
this.title = title;
}
public String getDept() {
return this.dept;
}
public int getNum() {
return this.num;
}
public String getTitle() {
return this.title;
}
}
int temp = arr[i];
arr[i] is Course, temp is int. You cannot assign a Course into an int variable, neither can you assign an int into a Course variable, because they are two completely different types.
Make your temp a Course:
Course temp = arr[i];
Ishamael's answer was correct. I will throw out this addition as you later may find it very useful to allow the user to sort by any field:
First you will need to add the Comparable interface to your Course class and write the compareTo() method. I've added an enum to the class to match each field you might want to sort by:
public class Course implements Comparable<Course>{
public static enum SortBy {
DEPARTMENT,
COURSE_NUM,
TITLE,
NOT_SORTED;
}
public static SortBy sortBy = SortBy.NOT_SORTED;
#Override
public int compareTo(Course course) {
if(sortBy == SortBy.DEPARTMENT) return getDept().compareTo(course.getDept());
if(sortBy == SortBy.COURSE_NUM) return getNum() - course.getNum();
if(sortBy == SortBy.TITLE) return getTitle().compareTo(course.getTitle());
return 0;
}
...
You can now modify your 'if' statement in your sort method to:
if (arr[j].compareTo(arr[min]) < 0) {
min = j;
}
Here is an example of using it now...
public static void main(String[] args) {
Course[] arr = {
new Course("dep-B", 3, "title-F"),
new Course("dep-C", 1, "title-E"),
new Course("dep-A", 2, "title-D")
};
System.out.println("Sorted by default (not sorted)");
System.out.println(Arrays.toString(arr));
System.out.println("Sorted by Department");
Course.sortBy = SortBy.DEPARTMENT;
sortByNumber(arr);
System.out.println(Arrays.toString(arr));
System.out.println("Sorted by Course Number");
Course.sortBy = SortBy.COURSE_NUM;
sortByNumber(arr);
System.out.println(Arrays.toString(arr));
System.out.println("Sorted by Title");
Course.sortBy = SortBy.TITLE;
sortByNumber(arr);
System.out.println(Arrays.toString(arr));
}
Related
Greetings StackOverFlow Community!
I have recently started studying java at school, and one of the assignments is to create a sorting method, like selection sort or insertion sort, without using java's own built-in functions. I have looked online a lot, and all of the methods I have found are for Arrays and not ArrayLists. The goal with the assignment is to sort a dog class after tail length, and if the dogs have the same tail length, to also sort after name.
So far this is what I have done;
Dog Class
public class Dog {
private static final double DEFAULT_TAIL_SIZE = 10.0;
private static final double DEFAULT_TAX_SIZE = 3.7;
private static int count;
private String name;
private String breed;
private int age;
private int weight;
private double tailLenght;
public Dog(String name, String breed, int age, int weight) {
//count++;
this.name = name;
this.age = age;
this.breed = breed;
this.weight = weight;
this.tailLenght = tailLenght;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getBreed() {
return breed;
}
public int getWeight() {
return weight;
}
public void setAge(int age) {
age = age <= 0 ? 1 : age;
}
public double getTailLength() {
if (breed.equals("Tax") || breed.equals("dachshund")||breed.equals("tax") || breed.equals("Dachshund")) {
return tailLenght = DEFAULT_TAX_SIZE;
} else {
return tailLenght = age * weight/DEFAULT_TAIL_SIZE;
}
}
#Override
public String toString() {
//System.out.println(String.format("name=%s breed=%s age=%d weight=%d taillenght=%.1f", name, breed, age, weight, getTailLength()));
return name + " " + breed + " " + age + " " + weight + " " + getTailLength();
}
And this is the sorting code I have made, that was not accepted due to the code using in-built java sorting methods. This is the only code I'm allowed to edit during this assignment
public class DogSorter {
public void sort(ArrayList<Dog> dogs) {
dogs.sort(new Comparator<Dog>() {
#Override
public int compare(Dog d1, Dog d2) {
int comparison = 0;
comparison = Double.valueOf(d1.getTailLength()).compareTo(d2.getTailLength());
if (comparison == 0) {
comparison = String.valueOf(d1.getName()).compareTo(d2.getName());
}
return comparison;
}
});
}
And lastly this is the runner code we received from our teachers
import java.util.ArrayList;
import java.util.Random;
public class DogSorterRunner {
private static final int NUMBER_OF_DOGS = 12;
private static final Random RND = new Random();
private static final String[] NAMES = { "Fido", "Karo", "Molly", "Bella", "Wilma", "Doris", "Sigge", "Charlie",
"Ludde", "Bamse", "Lassie", "Ronja", "Ratata", "Maki", "Dora", "Luna", "Spike", "Mumsan", "Cherie" };
private static final String[] BREEDS = { "Labrador", "Golden retriever", "Tax", "Dachshund" };
private static String getRandomValueFromArray(String[] array) {
return array[RND.nextInt(array.length)];
}
private static String randomName() {
return getRandomValueFromArray(NAMES);
}
private static String randomBreed() {
return getRandomValueFromArray(BREEDS);
}
private static int randomNumber() {
return RND.nextInt(10) + 1;
}
public static void main(String[] args) {
ArrayList<Dog> dogs = new ArrayList<>();
for (int n = 0; n < NUMBER_OF_DOGS; n++) {
Dog dog = new Dog(randomName(), randomBreed(), randomNumber(), randomNumber());
dogs.add(dog);
}
new DogSorter().sort(dogs);
for (Dog dog : dogs) {
System.out.println(dog);
}
}
Any help and feedback would be greatly appreciated!
The point of the assignment is that you should implement selection or insertion sort by yourself instead of using Java's built-in sort function. That is how you show some knowledge in implementing sorting algorithms.
Here is an example of a selection sort, which is based on your conditions (tail & name) and should give you a feeling of how the functions should look like. To do some more exercise, I suggest that you try to implement insertion sort by yourself.
public class DogSorter {
public void sort(ArrayList<Dog> dogs) {
dogs.sort(new Comparator<Dog>() {
#Override
public int compare(Dog d1, Dog d2) {
int comparison = 0;
comparison = Double
.valueOf(d1.getTailLength())
.compareTo(d2.getTailLength());
if (comparison == 0) {
comparison = String
.valueOf(d1.getName())
.compareTo(d2.getName());
}
return comparison;
}
});
}
public void selectionSort(ArrayList<Dog> dogs) {
int n = dogs.size();
// One by one move boundary of unsorted subarray
for (int i = 0; i < n - 1; i++) {
// Find the minimum element in unsorted array
int min_idx = i;
for (int j = i + 1; j < n; j++) {
Dog d1 = dogs.get(j);
Dog d2 = dogs.get(min_idx);
int comparison = Double
.valueOf(d1.getTailLength())
.compareTo(d2.getTailLength());
if (comparison == 0) {
comparison = String
.valueOf(d1.getName())
.compareTo(d2.getName());
}
if (comparison < 0)
min_idx = j;
}
// Swap the found minimum element with the first
// element
// using built in swap
// Collections.swap(dogs, min_idx, i);
// using classic temp method
Dog temp = dogs.get(min_idx);
dogs.set(min_idx, dogs.get(i));
dogs.set(i, temp);
// using classic method without temp element
// dogs.set(i, dogs.set(min_idx, dogs.get(i)));
}
}
}
Here is also a repl, where you can see this function in practice: https://repl.it/repls/VividMeekPlans
I am attempting to remove data from an array that I have added and want to specifically remove this data based on one variable to bring all the data from the array and then remove it.
Getting an error that says:
bad operand types for binary operator'-'
on line arr[j] = new Studnet(arr{j+i].Getid.........."
private void removeStudent() {
if(count == 0){
System.out.println("No Records");
} else {
Scanner intput = new Scanner(System.in);
System.out.println("Enter an ID: ");
String id = intput.next();
int res = 0;
int loc = 0;
Student[] temp = new Student[10];
for(int i = 0; i < count; i++) {
if(arr[i].getId().equals(id)){
for(int j = i; i < arr.length - 1; j++) {
arr[j] = new Student(arr[j+1].getId() - 1, arr[j+1].getFname(), arr[j+1].getLname(), arr[j+1].getAge());
}
loc = i;
res = 1;
}
}
temp = null;
count--;
arr = temp;
Scanner scanner = new Scanner(System.in);
System.out.println("Removed Record");
scanner.nextLine();
if(res == 1) {
} else
System.out.println("No Result");
}
}
This is my code on the separate file that has all the get functions
public class Student {
private String id;
private String fname;
private String lname;
private int age;
private int count;
Student(String id, String fname, String lname, int age, int count) {
this.id = id;
this.fname = fname;
this.lname = lname;
this.age = age;
this.count = count;
}
public String getId() {
return id;
}
public String getFname() {
return fname;
}
public String getLname() {
return lname;
}
public double getAge() {
return age;
}
public int getCount() {
return count;
}
}
You are trying to minus 1 on a string. That is why you got the error.
Do you want to try to get the ID in intger form, and then minus 1 so you can assign the previous ID to that student object?
If yes, try the below in order to convert it to integer and then minus 1:
Integer.parseInt(arr[j+1].getId())-1
Id is a string you cant calculate with it. (Like getId()- 1)
Edit:
This is a really simple example to show you, how it CAN work... but there different ways (maybe better ways) to solve your root problem. (See my first comment)
for(int j = i; i < arr.length - 1; j++){
int newId = Integer.parseInt(arr[j+1].getId()) -1;
arr[j] = new Student(Integer.toString(newId), arr[j+1].getFname(), arr[j+1].getLname(), arr[j+1].getAge());
}
I'm having an issue with a problem for homework.. the issues I am having are:
I have the following errors on my sort method:
The method sort(int[]) in the type Main is not applicable for the
arguments (Class)
studentArray cannot be resolved to a type
Syntax error, insert ". class" to complete ArgumentList
My toString method also doesnt seem to be putting out any information in the console.
HERE IS THE HOMEWORK PROBLEM:
For the lab this week, you will sort an array of objects - using any of the sort methods discussed in Chapter 23 or the Selection sort. It's your choice. Use the following criteria for your assignment:
The object class should be a Student with the following attributes:
id: integer
name: String
write the accessors, mutators, constructor, and toString().
In your main test class you will write your main method and do the following things:
Create an array of Student objects with at least 5 students in your array.
The sort method must be written yourself and included in the main class. The sort
method will sort based on student id.
Output the array out in unsorted order as it exists.
Sort the array
Output the sorted array
HERE IS MY MAIN CLASS:
public static void main(String[] args) {
Student studentArray[] = new Student[5];
for (int i=0; i < studentArray.length; i++) {
studentArray[i] = new Student();
}
studentArray[0].id = 5555;
studentArray[0].name = "Jim Jackson";
studentArray[1].id = 4444;
studentArray[1].name = "Craig Creedmoor";
studentArray[2].id = 3333;
studentArray[2].name = "Bill Biggums";
studentArray[3].id = 2222;
studentArray[3].name = "Frances Freeland";
studentArray[4].id = 1111;
studentArray[4].name = "Leslie Limerick";
for (int i = 0; i<5; i++) {
studentArray[i].toString();
}
sort(studentArray[]);
for (int i = 0; i<5; i++) {
studentArray[i].toString();
}
}
public void sort(int[] studentArray) {
for (int i = 1; i < studentArray.length; i++) {
int currentElement = studentArray[i];
int k;
for (k = i -1; k >=0 && studentArray[k] > currentElement; k--) {
studentArray[k + 1] = studentArray[k];
}
studentArray[k +1] = currentElement;
}
}
HERE IS MY STUDENT CLASS
public int id;
public String name;
Student() {
}
public int getID() {
return id;
}
public void setID(int i) {
this.id = i;
}
public String getName() {
return name;
}
public void setName(String n) {
this.name = n;
}
public String toString() {
return "The student's name is: " + this.name + "\n" +
"The student's ID is: " + this.id;
}
So according to the assignment instructions, here is what I got from it...
You needed a constructor in your student class, you were adding objects to the array improperly, Your sort method was also accessing the element within the array which is a "Student" and you were comparing it to type "int". To fix that I made the object in the student array actually access the ID.
Also.... Your sort method did not seem to work for me. The instructions said that you could use a selection sort so that is what I implemented instead. Let me know if you have questions.
This should work, let me know if it doesn't because I don't know how your Student class is defined within your project.
public static void main(String[] args) {
Student studentArray[] = new Student[5];
studentArray[0] = new Student(5555, "Jim Jackson");
studentArray[1] = new Student(4444, "Craig Creedmor");
studentArray[2] = new Student(3333, "Bill Biggums");
studentArray[3] = new Student(2222, "Frances Freeland");
studentArray[4] = new Student(1111, "Leslie Limerick");
sort(studentArray);
for (int i = 0; i<5; i++) {
System.out.println(studentArray[i].toString());
}
}
public static void sort(Student[] arr) {
for (int i = 0; i < arr.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < arr.length; j++)
if (arr[j].getID() < arr[index].getID())
index = j;
int smallerNumber = arr[index].getID();
String smallerString = arr[index].getName();
arr[index].setID(arr[i].getID());
arr[index].setName(arr[i].getName());
arr[i].setID(smallerNumber);
arr[i].setName(smallerString);
}
}
And then for Student class
public class Student {
private int id;
private String name;
public Student(int id, String name){
this.id = id;
this.name = name;
}
public int getID() {
return id;
}
public void setID(int i) {
this.id = i;
}
public String getName() {
return this.name;
}
public void setName(String n) {
this.name = n;
}
public String toString() {
return "The student's name is: " + this.name + "\n" +
"The student's ID is: " + this.id;
}
}
I am trying to output the names and corresponding scores in descending order. Having an array of strings and another array of integers, I am trying to relate the two arrays. I used Arrays.sort and tries to get the indices. The indices is then to be used to arrange the names in similar location as the corresponding scores. I have this code but I get run time error saying unfortunately, your app has stopped. Can anyone please help me on what to be done to achieve my goal here? Thank you so much!
int score[]= new int[4];
score[0]= 10;
score[1]= 50;
score[2]= 20;
score[3]= 60;
String names[] = new String[4];
names[0]= "player1";
names[1]= "player2";
names[2]= "player3";
names[3]= "player4";
Arrays.sort(score);
int index_array[] = new int[4];
int m = 0;
for(m = 0; m <4; m++){
index_array[m]=Arrays.binarySearch(score ,score[m]);
l = index_array[0];
}
for(int i = 0; i<4; i++){
if(l == score[i]){
j = i;
}
}
String name = names[m];
show.setText(name + " " + Integer.toString(l));
Create Player model which holds player's name and score and then use Comparator to sort players by score.
Player model:
class Player {
private String name;
private int score;
public Player(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public String toString() {
return "name=" + name + "; score=" + score;
}
}
Comparator:
class PlayerComparator implements Comparator<Player> {
public int compare(Player p1, Player p2) {
return p1.getScore() < p2.getScore() ? -1
: p1.getScore() > p2.getScore() ? 1 : 0;
}
}
And an example of usage:
public class PlayerTest {
public static void main(String[] args) {
int score[]= new int[4];
score[0]= 10;
score[1]= 50;
score[2]= 20;
score[3]= 60;
String names[] = new String[4];
names[0]= "player1";
names[1]= "player2";
names[2]= "player3";
names[3]= "player4";
Player[] players = new Player[names.length];
for(int i = 0; i < names.length; i++) {
players[i] = new Player(names[i], score[i]);
}
Arrays.sort(players, new PlayerComparator());
}
}
you need to associate the score and the user name. Currently, you are associating them by array index. when you sort the scores, the indices of the scores will change.
Try something like this:
class Score implements Comparable<Score>
{
int score;
String player;
public Score(int theScore, String thePlayer)
{
score = theScore;
player = thePlayer;
}
public int compareTo(Score)
{
... compare based on the int score value ...
}
... getters. setters optional ...
}
List<Score> scoreList = new ArrayList<Score>();
... fill scoreList with Score objects. ...
Collections.sort(scoreList);
This is a design smell. You shouldn't have two parallel arrays. Instead, you should have a single array of Player objects, where each Player would have a name and a score.
Storing the arra of players by name or by score would then be extremely simple.
Java is an OO language. Use objects.
public class Player
private final String name;
private int score;
public Player(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
...
Player[] players = new Player[4];
players[0] = new Player("player1", 10);
...
I am doing a project and instead of using an array, I figured an array list would be better. I know I need to declare the array list and its methods, but I am not too sure where to go from there. Any suggestions? Here's code...
public class Student {
private String name;
private int[] tests;
public Student() {
this("");
}
public Student(String nm) {
this(nm, 3);
}
public Student(String nm, int n) {
name = nm;
tests = new int[n];
for (int i = 0; i < tests.length; i++) {
tests[i] = 0;
}
}
public Student(String nm, int[] t) {
tests = new int[t.length];
}
public Student(Student s) {
this(s.name, s.tests);
}
public int getNumberOfTests() {
return tests.length;
}
public void setName(String nm) {
name = nm;
}
public String getName() {
return name;
}
public void setScore(int i, int score) {
tests[i - 1] = score;
}
public int getScore(int i) {
return tests[i - 1];
}
public int getAverage() {
int sum = 0;
for (int score : tests) {
sum += score;
}
return sum / tests.length;
}
public int getHighScore() {
int highScore = 0;
for (int score : tests) {
highScore = Math.max(highScore, score);
}
return highScore;
}
public String toString() {
String str = "Name: " + name + "\n";
for (int i = 0; i < tests.length; i++) {
str += "test " + (i + 1) + ": " + tests[i] + "\n";
}
str += "Average: " + getAverage();
return str;
}
public String validateData() {
if (name.equals("")) {
return "SORRY: name required";
}
for (int score : tests) {
if (score < 0 || score > 100) {
String str = "SORRY: must have " + 0 + " <= test score <= " + 100;
return str;
}
}
return null;
}
}
I figured an array list would be better
Maybe. Maybe not. It depends. Does it look like you would get a benefit in using one based on the ArrayList API?
If your "list" never changes size, and you don't need to find things in it, then an array is just as good.
I know I need to declare the array list and its methods, but I am not
too sure where to go from there
You need to create a reference to an instance of an ArrayList. That's as simple as
List<Integer> myList = new ArrayList<Integer>();
in your class declaration. You don't need to "declare its methods". When you have a reference to an object, you can invoke its methods.
To use an ArrayList, you just need to declare and instantiate it:
// <SomeObject> tells Java what kind of things go in the ArrayList
ArrayList<SomeObject> aDescriptiveNameHere = new ArrayList<SomeObject>();
// This is also valid, since an ArrayList is also a List
List<SomeObject> list = new ArrayList<SomeObject>();
Then you can add things with the add() method:
// Please don't name your list "list"
list.add(new Thing(1));
list.add(new Thing(2));
You can get something by index (like you would with someArray[index]) as:
list.get(index);
// For example
Thing t = list.get(5);
You probably also need the size().
See the JavaDocs for more info.
All of the operations you're using are mirrored in the ArrayList API. One thing that's worth noting is that you cannot declare an ArrayList of primitive types, but for each of the primitive types there exists an Object that is the boxed version of the primative.
The boxed version of int is Integer, so you have
ArrayList<Integer> myList = new ArrayList<Integer>();
From there, you need to look up the methods you would need to use in order to manipulate the array. For example, if you want to add the number 42 to the end of the array, you would say
myList.add(42);
The ArrayList API is located here.
I think it could be better to use the stl vector instead make your own arrays
I tried to change the array to arraylist.
Reply if this doesn't compile correctly.
import java.util.ArrayList;
public class Student {
private String name;
// private int[] tests;
private ArrayList<Integer> tests;
public Student() {
this("");
}
public Student(String nm) {
// this(nm, 3);
name = nm;
}
/*
* public Student(String nm, int n) { name = nm; tests = new int[n]; for
* (int i = 0; i < tests.length; i++) { tests[i] = 0; } }
*/
/*
* public Student(String nm, int[] t) { tests = new int[t.length]; }
*/
public Student(Student s) {
this(s.name, s.tests);
}
public Student(String name2, ArrayList<Integer> tests2) {
name = name2;
tests = tests2;
}
public int getNumberOfTests() {
return tests.size();
}
public void setName(String nm) {
name = nm;
}
public String getName() {
return name;
}
// public void setScore(int i, int score) {
// tests[i - 1] = score;
public void setScore(int score) {
tests.add(score);
}
public int getScore(int i) {
// return tests[i - 1];
return tests.get(i - 1);
}
public int getAverage() {
int sum = 0;
for (int score : tests) {
sum += score;
}
// return sum / tests.length;
return sum / tests.size();
}
public int getHighScore() {
int highScore = 0;
for (int score : tests) {
highScore = Math.max(highScore, score);
}
return highScore;
}
public String toString() {
String str = "Name: " + name + "\n";
for (int i = 0; i < tests.size(); i++) {
str += "test " + (i + 1) + ": " + tests.get(i) + "\n";
}
str += "Average: " + getAverage();
return str;
}
public String validateData() {
if (name.equals("")) {
return "SORRY: name required";
}
for (int score : tests) {
if (score < 0 || score > 100) {
String str = "SORRY: must have " + 0 + " <= test score <= "
+ 100;
return str;
}
}
return null;
}
public ArrayList<Integer> getTests() {
return tests;
}
public void setTests(ArrayList<Integer> tests) {
this.tests = tests;
}
}