In Java, I have a set like this:
Set<Student> studentsSet = new HashSet<Student>();
Can someone give an example of how to use this in an example?
Expounding what I had mentioned as a comment:
Use the rollNumber as an identity, in order to implement the equals() and hashcode() methods. For example, the Student class could look like:
class Student {
private int rollNumber;
private String name;
public Student(int rollNumber, String name) {
this.rollNumber = rollNumber;
this.name = name;
}
#Override
public int hashCode() {
return rollNumber;
}
#Override
public boolean equals(Object obj) {
Student other = (Student) obj;
return (rollNumber == other.rollNumber);
}
}
You could delete a student this way - note that only the roll number will have a bearing on what gets deleted from the set, which is in line with what the equals and hashcode look for:
Set<Student> students = new HashSet<Student>();
students.remove(new Student(3, "I don't care what her/his name is!"));
Related
I have a class Person with the attributes of name (string) and age (int):
public class Person {
private String name;
private int age;
public Hero(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
I created a list of Person, and compared them using age.
List<Person> persons = new ArrayList<>();
persons.add("Andrew", 18);
persons.add("Barry", 25);
persons.add("Cynthia", 33);
persons.add("Darwin", 33);
Collections.sort(persons, new Comparator<Person>() {
#Override
public int compare(Person lhs, Person rhs) {
return lhs.getAge() < rhs.getAge() ? -1 : lhs.getAge() == lhs.getAge() ? 0 : 1;
}
});
If the ages of two items are equal, how do I compare them using the name instead?
Starting with Java 8, creating a custom Comparator is much easier, and you can compare multiple fields.
You can use the following code:
Comparator.comparing(Person::getAge).thenComparing(Person::getName)
And that's it.
You can use it to sort your collection like this:
Collections.sort(filteredList, Comparator.comparing(Person::getAge).thenComparing(Person::getName))
class Person
{
private String name;
private String profession;
}
profession has values:
engineer
Doctor
Teacher
student
I have list of person and want to sort it on the basis of Profession.
engineer comes first then Doctor and then Teacher and then student.
Is it possible to sort it with comparable interface.
You can sort your custom object using Collection.sort method like this,
Collections.sort(list, new Comparator(){
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
return p1.getProfession().compareToIgnoreCase(p2.getProfession());
}
});
To Sort in reverse order just make your return statement line like this,
p2.getProfession().compareToIgnoreCase(p1.getProfession());
This will directly make your list sorted.
Add enum to your variables:
class Person {
private String name;
private String profession;
private enum enumProffesion
{
Doctor, Teacher, student;
}
}
After that could add function to the Person class which would give you value of the profession:
public int professionValue()
{
enumProffesion enumValue= enumProffesion.valueOf(proffesion);
switch (enumValue) {
case Doctor: return 1; break;
case Teacher: return 2; break;
case student: return 3; break;
default: return null;
}
}
After that you just implement logic that will sort all Persons. For that you can help your self with this answer: sorting integers in order lowest to highest java
Implement Comparable
Yes you can implement Comparable. Create a method compareTo(Person obj) and then write your custom logic. You can compare alphabetically or whatever other algorithm you want - for example engineer before doctor because he makes more money :) For alphabetic comparing you can do it like that:
class Person implements Comparable<Person> {
#Override
public int compareTo(Person o) {
return this.profession.compareTo(o.getProfession());
}
private String name;
private String profession;
}
After that you just use the Collections.sort
Enum
You can do it easily if replace profession field by enum:
class Person implements Comparable<Person> {
private String name;
private Profession profession;
// by this we'll define natural ordering based on ordering
// in which `Profession` enum values are declared
#Override
public int compareTo(Person p) {
return this.profession.compareTo(p.profession);
}
}
And here's Profession enum:
public enum Profession {
ENGINEER("engineer"), DOCTOR("Doctor"), TEACHER("Teacher"), STUDENT("student");
private String displayName;
Profession(String dn) {
this.displayName = dn;
}
#Override
public String toString() {
return this.displayName;
}
}
If you are new to the enum facility in Java, see Oracle tutorial.
Add getter and setter for profession in Person class and simply use below code
class Person {
private String name;
private String profession;
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
}
List<Person> personList = new ArrayList<Person>();
Person p1 = new Person();
p1.setProfession("Engineer");
personList.add(p1);
Person p2 = new Person();
p2.setProfession("Doctor");
personList.add(p2);
Person p3 = new Person();
p3.setProfession("Teacher");
personList.add(p3);
Person p4 = new Person();
p4.setProfession("student");
personList.add(p4);
Collections.sort(personList, new Comparator() {
#Override
public int compare(Object obj1, Object obj2) {
Person p1 = (Person)obj1;
Person p2 = (Person)obj2;
return p1.getProfession().compareToIgnoreCase(p2.getProfession());
}
});
Two ways:
Implement the Comparable interface
Create a Comparator
With the first way you can sort the collection only by the one method compareTo you will define
Your Person.java
class Person implements Comparable<Person> {
private String name;
private String profession;
#Override
public int compareTo(Person o) {
return this.profession.compareTo(o.getProfession());
}
public String getName() {
return name;
}
public String getProfession() {
return profession;
}
}
Then you need to call:
Collections.sort(yourCollection);
With the second way you can sort by one or more Comparator, giving you the ability to compare the same collection with different criteria.
Example of two Comparator
public class PersonSortByNameComparator implements Comparator<Person>{
#Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
public class PersonSortByAlphabeticalProfessionComparator implements Comparator<Person>{
#Override
public int compare(Person p1, Person p2) {
return p1.getProfession().compareTo(p2.getProfession());
}
}
Or this one you need:
public class PersonSortByProfessionComparator implements Comparator<Person> {
#Override
public int compare(Person p1, Person p2) {
if(p1.getProfession().equalsIgnoreCase(p2.getProfession())
return 0;
if(p1.getProfession().equalsIgnoreCase("student")
return -1;
if(p1.getProfession().equalsIgnoreCase("engineer")
return 1;
if(p1.getProfession().equalsIgnoreCase("doctor")
return 1;
else
return -1;
}
}
And then call one of them:
Collections.sort(yourCollection, new PersonSortByNameComparator());
This blog article is really good written and you can some examples
My suggestion -
1. Create a new class Profession -
class Profession{
public Profession(Integer id, String prefessionName){
this.id=id;
this.prefessionName=prefessionName;
}
Integer id;
String professionName;
}
2. Now give Id to each Profession object/instance maintaining the order. For example -
Profession engineer = new Profession(1, "Engineer"); //since Engineer is in first place
Profession doctor = new Profession(2, "Doctor"); //since Doctor is in second place
Profession teacher = new Profession(3, "Teacher");
Profession student = new Profession(4, "Student");
3. Now sort the Profession for id using compareable interface.
Alright so, I am building an online registration system for a university. It's a fairly basic system written in java so there's no database issue to worry about. My problem is this: I have a class of objects called Course. Each course has a list of attribute (id, time, instructor, etc.). Each user then, has an arraylist (or schedule if you will) of Course objects which they can add or remove. My question is how do I create an arraylist for each student/user? Would it be beneficial to have a separate arraylist of Courses like a catalog from which to choose from? Any advice on the subject would be of help. If you'd like to see an example of my code thus far let me know and I'll edit my post to include it.
public class Course {
private int courseId;
private String courseDes;
private String courseIns;
private int time;
public Course(int courseId, String courseDes, String courseIns, int time) {
courseId = this.courseId;
courseDes = this.courseDes;
courseIns = this.courseIns;
time = this.time;
}
No need to use maps; you've expressed the right relationship yourself: "Each user has an ArrayList". The way to express a has-a relationship is with instance fields:
public class Student {
private final List<Course> courses = new ArrayList<>();
//write methods that operate on courses, or make courses public
....
Representing courses as a Course object is simplest if you care about the properties of the courses in any way. If however you only need the know the course ID, or if you need to be storing a large amount of Students, you can save space by storing courses as integers or shorts and looking them up in a static table.
I would have three separate classes Courses, Student and Enrollment.
public class Course {
private int courseId;
private String courseDes;
private String courseIns;
private int time;
public Course(int courseId, String courseDes, String courseIns, int time) {
courseId = this.courseId;
courseDes = this.courseDes;
courseIns = this.courseIns;
time = this.time;
}
}
Student
public class Student {
private final int studentID;
private final String name;
private Set<Course> studentCourses;
public Student(int studentId, String name) {
this.name = name;
this.studentID = studentId;
}
public String getName(){
return this.name;
}
public int getStudentId(){
return this.studentID;
}
void addCourse(Course course) {
if(!studentCourses.contains(course)){
studentCourses.add(course);
}
else{
studentCourses.remove(course);
studentCourses.add(course);
}
}
#Override
public int hashCode() {
int hash = 7;
hash = 23 * hash + this.studentID;
hash = 23 * hash + (this.name != null ? this.name.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Student other = (Student) obj;
if (this.studentID != other.studentID) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
return true;
}
}
Enrollment
class Enrollment{
//This Map will group student with the same name
private Map<String, List<Student>> enrollment;
public Enrollment(Student student){
if(enrollment.containsKey(student.getName())){
enrollment.get(student.getName()).add(student);
}else
{
List<Student> newStudent = new ArrayList<Student>();
newStudent.add(student);
enrollment.put(student.getName(), newStudent);
}
}
public void addCourse(Student student, Course course){
try{
List<Student> studentSameName = enrollment.get(student.name);
for(Student studentEntry : studentSameName){
if(studentEntry.getStudentId() == student.getStudentId()){
studentEntry.addCourse(course);
}
}
}catch(NullPointerException e){
//student does not exist
//TODO Add Logic
}
}
public void removeStudent(Student student){
//TODO Add Logic
}
}
So if I have a class of Person, where you can define their name, age and date of birth.
public class Person
{
private String name;
private int age;
private String dOB;
public Person (String name, int age, String dateOfBirth)
{
this.name = name;
this.age = age;
dOB = dateOfBirth;
}
}
Then in another class of Memberships, I have an arrayList called Members. I know how to add a Person by:
import java.util.ArrayList;
public class Memberships
{
private ArrayList<Person> members;
public Memberships()
{
members = new ArrayList<Person>();
}
public void addMember(Person person)
{
members.add(person);
}
}
However how do I add a member without separately creating an instance of Person.
So starting with:
public void addMember(String name, int age, String dOB)
{
}
This is where I get stuck I have no idea how to take these values to create a Person to add to my members ArrayList.
#dehlen Sorry!
public void addNewMember(String name, int age, String dOB)
{
Person p = new Person(name, age, dOB);
for (Person pers : members)
{
if (pers.getName().equals(name))
{
System.out.print("This member is already included.");
}
else
{
members.add(p);
}
}
}
So I did this, however the Person is never added? I'm confused as to why?
You need to create an instance of Person, since this is what your ArrayList expects.
Here is how you can complete your task:
public void addMember(String name, int age, String dOB)
{
Person p = new Person(name,age,dOB);
members.add(p);
}
To make sure you do not add duplicates to your ArrayList you could iterate over your ArrayList and look if there is a Person object with the same values already in it.
public void addMember(String name, int age, String dOB)
{
//Create a new Person instance with given parameters
Person p = new Person(name,age,dOB);
//Loop through existing Person instances in ArrayList
for (Person pers : members){
//If there exists a Person with the same name
if (pers.getName().equals(name)) {
//We can stop searching for a duplicate and leave the method
return;
}
}
//Since we did not exit the method above we did not found any duplicate, therefore it is safe to add our Person instance to our ArrayList
members.add(p);
}
Of course this only checks whether there is a Person with the same name. But I with the help of this code you can accomplish also to check further properties.
Also I use a method called getName() which is called a getter. This method has to be specified in your Person model class:
public String getName() {
return name;
}
As #BorisTheSpider pointed out correctly there is a better approach to test equality.
You can/should override the equals() method of your model class like so:
#Override
public boolean equals(Object person)
{
boolean same = false;
if (person != null && person instanceof Person)
{
same = this.name == ((Person) person).name;
}
return same;
}
Then you can use use the contains() method as following:
members.contains(p);
To check your other properties too you should implement the logic in the overidden equals() method.
Simply create a Person instance, and then you can pass it into your existing addMember method that takes a person.
public void addMember(String name, int age, String dateOfBirth) {
this.addMember(new Person(name, age, dateOfBirth);
}
I have HashSet which contain list of objects as Student and professor and department. It needs to check which student have the highest marks and professor which have student with highest marks in total. The sample code represent like
class Student{
public String Name;
public int Age;
public int TotalMarks;
}
class Professor{
public String Name;
public int Age;
public Student Student_Assigned;
}
class Department{
Set<Professor> collectionDept = new HashSet<Professor>();
public Student getStudentWithHigestMarks(){
return null;
}
}
How can I find this using java?
Implement Comparable and sort/manipulate your Collection.
For instance in your main code:
Student bad = new Student("bad");
bad.setMarks(2);
Student meh = new Student("meh");
meh.setMarks(5);
Student good = new Student("good");
good.setMarks(10);
Student otherGood = new Student("otherGood");
otherGood.setMarks(10);
// initializes a Set of students
Set<Student> students = new HashSet<Student>();
// adds the students
students.add(meh);
students.add(bad);
students.add(good);
students.add(otherGood);
// prints the "best student"
System.out.println(Collections.max(students).getName());
// initializing Set of best students
List<Student> bestStudents = new ArrayList<Student>();
// finding best mark
int bestMark = Collections.max(students).getMarks();
// adding to best students if has best mark
for (Student s: students) {
if (s.getMarks() == bestMark) {
bestStudents.add(s);
}
}
// printing best students
for (Student s: bestStudents) {
System.out.println(s.getName());
}
Output:
good
good
otherGood
... and here's a draft of your Student class:
public class Student implements Comparable<Student> {
// we use encapsulation and set the fields' access to private
private String name;
private int age;
private int marks;
// we use encapsulation and have setters/getters/constructor access for the private fields
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
// TODO other setters/getters
// here we implement the compareTo method and decide which int to return according to the "marks" field
#Override
public int compareTo(Student otherStudent) {
if (marks < otherStudent.getMarks()) {
return -1;
}
else if (marks > otherStudent.getMarks()) {
return 1;
}
else {
return 0;
}
}
You may also want to take a closer look at the documentation for the Comparable interface.
Use a TreeSet instead. It has a constructor taking a Comparator. It will automatically sort the Set.
Converter:
Set<YourObject> hashSet = getItSomehow();
Set<YourObject> treeSet = new TreeSet<YourObject>(new YourComparator());
treeSet.addAll(hashSet);
Docs:
http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
Use this:
public Student getStudentWithHigestMarks() {
Student highest = null;
for(Professor professor: collectionDept) {
if(highest == null) {
highest = professor.Student_Assigned;
} else if(highest.TotalMarks < professor.Student_Assigned.TotalMarks) {
highest = professor.Student_Assigned;
}
}
return highest;
}
For student with the highest marks:
If you implement the Comparable interface in the Student and Professor classes you can simply use the standard Java Collections.max
Set<Student> students = ...;
Student highestMarks = Collections.max(students);
If you include the student's highest mark in the Professor's compareTo method, you
simply do
Professor professor = Collections.max(professors)