Generics: java.lang.String cannot be applied to Student - java

I am in class and my professor is saying her code works and there is nothing wrong with it and that it must be me. I have looked over her code and copied it word for word like she stated however I am still receiving the error:
Pair.java:28: set(java.lang.String,java.lang.Double) in Pair cannot be applied to (Student,java.lang.Double)
The part I bolded is the part I receive an error on. Are the set methods incorrect? Because the line with the error goes back to the set methods
This is her code:
Student.java
import java.io.*;
public class Student implements Person {
String id;
String name;
int age;
//constructor
public Student(String i, String n, int a) {
id = i;
name = n;
age = a;
}
public String getID() {
return id;
}
public String getName() {
return name; //from Person interface
}
public int getAge() {
return age; //from Person interface
}
public void setid(String i) {
this.id = i;
}
public void setName(String n) {
this.name = n;
}
public void setAge(int a) {
this.age = a;
}
public boolean equalTo(Person other) {
Student otherStudent = (Student) other;
//cast Person to Student
return (id.equals(otherStudent.getID()));
}
public String toString() {
return "Student(ID: " + id +
",Name: " + name +
", Age: " + age +")";
}
}
Person.java
import java.io.*;
public interface Person {
//is this the same person?
public boolean equalTo (Person other);
//get this persons name
public String getName();
//get this persons age
public int getAge();
}
Pair.java
import java.io.*;
public class Pair<K, V> {
K key;
V value;
public void set (K k, V v) {
key = k;
value = v;
}
public K getKey() {return key;}
public V getValue() {return value;}
public String toString() {
return "[" + getKey() + "," + getValue() + "]";
}
public static void main (String [] args) {
Pair<String,Integer> pair1 =
new Pair<String,Integer>();
pair1.set(new String("height"),new
Integer(36));
System.out.println(pair1);
Pair<String,Double> pair2 =
new Pair<String,Double>();
//class Student defined earlier
**pair2.set(new Student("s0111","Ann",19),**
new Double(8.5));
System.out.println(pair2);
}
}

For the instantiation:
Pair<String,Double> pair2 = new Pair<String,Double>();
your set() method signature is equivalent to: set(String, Double). And you are passing it a Student reference in the below invocation, which wouldn't work, as Student is not a String.
pair2.set(new Student("s0111","Ann",19), new Double(8.5));
To avoid the issue, change the declaration of pair2 to:
Pair<Student,Double> pair2 = new Pair<Student,Double>();

The error is pretty self explanatory. pair2 is defined as a Pair<String, Double>. You're trying to set a Student, Double. That won't work.

Pair<String,Double> pair2 = new Pair<String,Double>();
should be:
Pair<Student,Double> pair2 = new Pair<Student,Double>();

from your code pair2 is defined as type Pair<String,Double>,i.e pair2 set() method expecting String ,Double as arguments,but you are passing Student , Double.
So
Pair<String,Double> pair2 = new Pair<String,Double>();
should be
Pair<Student,Double> pair2 = new Pair<Student,Double>();

Related

How do I print out an array list containing both the name of a student and the id of a student?

public class pro1{
static ArrayList <String> student = new ArrayList<String>();
static ArrayList <Integer> id = new ArrayList<Integer>();
String name;
int ID;
public pro1() {
this.name = "";
this.ID = 0;
}
public pro1(String name, int ID) {
this.name = name;
this.ID = ID;
}
public boolean addStudent(String name, int ID) {
student.add(name);
id.add(ID);
return true;
}
/*#Override
public String toString() {
return name + ID;
}*/
public static void main(String args[]) {
pro1 stu = new pro1();
stu.addStudent("john", 1);
stu.addStudent("johnny", 2);
System.out.println(stu);
}
}
I want to print out both the name of the student and the student id using ArrayList. however, I'm not sure how to do that since in this class I can only print out the ArrayList of names or the ArrayList of id. I'm thinking of maybe using another class to create a student object, but I'm not sure how to do so.
great question, I think the best solution for this would be to create a Student object just like you thought!
public static class Student {
private final String name;
private final int id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
#Override
public String toString() {
return String.format("name=%s, id=%s", name, id);
}
}
public static class School {
private final List<Student> students;
public School(List<Student> students) {
this.students = students;
}
public void add(Student student) {
students.add(student);
}
public List<Student> getStudents() {
return students;
}
}
public static void main(String... args) {
School school = new School(new ArrayList<>());
school.add(new Student("jason", 1));
school.add(new Student("jonny", 2));
school.getStudents().forEach(System.out::println);
}
Non-OOP
Loop the pair of lists.
First sanity-check: Are the two lists the same size?
if( students.size() != ids.size() ) { … Houston, we have a problem }
Then loop. Use one index number to pull from both lists.
for( int index = 0 ;
index < students.size() ;
index ++
)
{
System.out.println(
students.get( index ) +
" | " +
ids.get( index )
) ;
}
OOP
The object-oriented approach would be to define a class. The class would have two member fields, the name and the id of the particular student.
Then create a method that outputs a String with your desired output.
All this has been covered many times on Stack Overflow. So search to learn more. For example: Creating simple Student class and How to override toString() properly in Java?
Uncomment and modify your toString() method as below. It will print both student and id.
#Override
public String toString() {
return student.toString() + id.toString();
}
If you want to have Student to Id mapping, best is to have them in Map collection. Id as key and student name as value.

How to look though a list of Objects to find a match?

I'm trying to compare a bunch of Objects of the same class to search for matching ID's?
This is the GroupClass, when a new entry is entered it will test against the idNumber to see if there is a match.
Public GroupClass {
private int idNumber;
private String name;
private double income;
public GroupClass(int id, String name, double income){
this.idNumber = id;
this.name = name;
this.income = income;
}
public int getIdNumber() {
return idNumber;
}
public void setIdNumber(int idNumber) {
this.idNumber = idNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getIncome() {
return income;
}
public void setIncome(double income) {
this.income = income;
}
}
This is the Main Method
import static java.lang.reflect.Array.set;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
public class ListTester {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Set<GroupClass> groupArray = new LinkedHashSet<>();
System.out.println("Enter a ID Number");
int id = input.nextInt();
System.out.println("Enter a First Name");
String name = input.next();
System.out.println("Enter a an Income");
double income = input.nextDouble();
groupArray.add(new GroupClass(1111, "Billy", 178000));
groupArray.add(new GroupClass(1112, "Sam", 78000));
groupArray.add(new GroupClass(1113, "Mark", 79000));
groupArray.add(new GroupClass(id, name, income));
printTheClass(groupArray);
}
public static void printTheClass(Set group){
for(Object theArray: group){
System.out.println(theArray + " ");
}
}
}
Ive seen a few questions like it but just cant get it to work for my particular case, thanks in advance.
As per the above comment you override the equals method, but this may not be suitable for the long term growth of the class.
But using your existing code try
public static void printTheClass(Set<GroupClass> group){
for(GroupClass theArray: group){
System.out.println(theArray + " ");
}
}
and
public static GroupClass findTheClass(Set<GroupClass> group, int id){
for(GroupClass obj: group){
if(obj.getIdNumber == id) return obj;
}
return null;
}
This can be used as
if (findTheClass (groupArray, id) == null) {
groupArray.add (new GroupClass(id, name, income));
}
Not quite sure what is your goal. If you want to reject any new entry if the id already exist, you need to override the hashCode and equals methods of the GroupClass so that LinkedHashSet knows if two GroupClass objects are different:
#Override
public int hashCode() {
return this.idNumber;
}
#Override
public boolean equals(Object obj) {
return obj instanceof GroupClass && ((GroupClass) obj).getIdNumber() == this.idNumber;
}
However, in most cases, you might want to retrieve an entry using its id number. Then it might be better to use a map with id as key, and the GroupoClass object itself as value
Map<Integer, GroupClass> groupmap = new HashMap<>()
groupmap.put(id, new GroupClass(id, name, income));
and you will have to use groupmap.keySet() to iterate the map.

Value added to array is NULL?

In my code below, I am experiencing a problem I am unable to get around... when I add a class Person object to an array, it appears to add fine, however when I attempt to print out that object value form a specified array position, it outputs "null."
Here is the code
import java.util.Scanner;
import java.util.Arrays;
import java.lang.String;
public class Main
{
public static void main(String[] args)
{
int ARRAY_LENGTH = 2;
Scanner in = new Scanner(System.in);
Person[] Persons;
Persons = new Person[ARRAY_LENGTH];
for (int i = 0; i < ARRAY_LENGTH; i++)
{
System.out.println("Enter a name to add to the array: ");
Persons[i] = new Person(in.next());
System.out.println(Persons[i]);
}
Arrays.sort(Persons);
for (int i = 0; i < ARRAY_LENGTH; i++)
{
System.out.println(Persons[i]);
}
}
}
&
public class Person implements Comparable<Person>
{
private String name;
public Person (String aName)
{
String name = aName;
}
public String getName()
{
return name;
}
public int compareTo(Person o)
{
Person other = (Person) o;
if (this.name.equals(o.name))
{
return 0;
}
if (this.name.compareTo(o.name) < 0)
{
return -1;
}
return 1;
}
#Override
public String toString()
{
return name;
}
}
No, it hasn't added null to the array. It's put a reference to a Person object in the array, and when you call toString() on that Person object, it's returning the value of the name field... which is always null, because of this constructor:
public Person (String aName)
{
String name = aName;
}
That isn't assigning a value to the name field - it's declaring a local variable called name. (I'd expect a decent IDE to issue a warning about that.)
You want:
public Person (String aName)
{
name = aName;
}
The constructor
public Person (String aName)
{
String name = aName;
}
stores the name in a local variable.
Change this to
public Person (String aName)
{
this.name = aName;
}
The constructor is wrong
public Person (String aName)
{
String name = aName;
}
it is creating a new variable instead of assigning the field properly.
Try removing the type declaration:
public Person (String aName)
{
name = aName;
}

Uncompilable source code when using Comparator in Java

I'm getting the following error when trying to run this little program:
Exception in thread "main" java.lang.ExceptionInInitializerError
at MainClass.main(Person.java:120)
Caused by: java.lang.RuntimeException: Uncompilable source code - FirstNameComparator is not abstract and does not override abstract method compare(java.lang.Object,java.lang.Object) in java.util.Comparator
at FirstNameComparator.<clinit>(Person.java:71)
... 1 more
Java Result: 1
Please tell me what I'm doing wrong, and of course it would help a short example with explanations about how to properly use Comparator and Comparable.
import java.util.*;
import java.lang.*;
public class Person implements Comparable {
private String firstName;
private String lastName;
private int age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName= lastName;
}
public String getLastName() {
return lastName;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return age;
}
#Override
public int compareTo(Object anotherPerson) throws ClassCastException {
if(!(anotherPerson instanceof Person)) {
throw new ClassCastException("A person object expected !");
}
int anotherPersonAge = ((Person)anotherPerson).getAge();
return this.age = anotherPersonAge;
}
}
LastNameComparator.java
class LastNameComparator implements Comparator {
public int compareTo(Object person, Object AnotherPerson) {
String lastName1 = ((Person)person).getLastName().toUpperCase();
String firstName1= ((Person)person).getFirstName().toUpperCase();
String lastName2 = ((Person)person).getLastName().toUpperCase();
String firstName2 = ((Person)person).getFirstName().toUpperCase();
if(lastName1.equals(lastName2)) {
return firstName1.compareTo(firstName2);
}else {
return lastName1.compareTo(lastName2);
}
}
}
FirstNameComparator.java
class FirstNameComparator implements Comparator {
public int compareTo(Object person, Object anotherPerson) {
String lastName1 = ((Person)person).getLastName().toUpperCase();
String firstName1 = ((Person)person).getFirstName().toUpperCase();
String lastName2 = ((Person) person).getLastName().toUpperCase();
String firstName2 = ((Person) person).getFirstName().toUpperCase();
if(firstName1.equals(lastName1)) {
return lastName1.compareTo(lastName2);
}else {
return firstName1.compareTo(firstName2);
}
}
}
MainClass.java
class MainClass {
public static void main(String[] args) {
Person[] persons = new Person[4];
persons[0] = new Person();
persons[0].setFirstName("Asaftei");
persons[0].setLastName("Ionut");
persons[0].setAge(25);
persons[1] = new Person();
persons[1].setFirstName("Binoclu");
persons[1].setLastName("Telescop");
persons[1].setAge(10);
persons[2] = new Person();
persons[2].setFirstName("Morcov");
persons[2].setLastName("Castravete");
persons[2].setAge(33);
persons[3] = new Person();
persons[3].setFirstName("Rosie");
persons[3].setLastName("Ardei");
persons[3].setAge(55);
System.out.println("Natural Order : ");
for(int counter =0; counter<=3; counter++) {
Person person = persons[counter];
String lastName=person.getLastName();
String firstName=person.getFirstName();
int age = person.getAge();
System.out.println(lastName+ ", " +firstName+ " , "+age);
}
Arrays.sort(persons, new FirstNameComparator());
System.out.println();
System.out.println("Sorted by First Name: ");
for(int counter=0; counter<=3; counter++) {
Person person = persons[counter];
String lastName = person.getLastName();
String firstName = person.getFirstName();
int age = person.getAge();
System.out.println(lastName+ ", " +firstName+ ", " +age );
}
Arrays.sort(persons, new LastNameComparator());
System.out.println();
System.out.println("Sorted by Last Name"); for(int counter=0; counter<=3; counter++) {
Person person = persons[counter];
String lastName = person.getLastName().toUpperCase();
String firstName = person.getFirstName().toUpperCase();
int age = person.getAge();
System.out.println(lastName +", "+firstName+", "+age);
}
}
}
Comparators need to implement the compare method, not a compareTo method.
So, e.g., your FirstNameComparator should look like this:
class FirstNameComparator implements Comparator {
#Override
public int compare(Object person, Object anotherPerson) {
// implementation
}
}
Note that since this Comparator is used to compare Person instances, it would be a better practice to use generics syntax and define it as such:
class FirstNameComparator implements Comparator<Person> {
#Override
public int compare(Person person, Person anotherPerson) {
// implementation
}
}
Don't forget Comparable takes in generic type arguments.
So use implements Comparable<Person> instead. This means that you can compare two Persons.
Also an overriding method is not allowed to add additional throws to the method. See this question
The new definition should be something like this:
#Override
public int compareTo(Person other) {
return Intger.compare(this.getAge(), other.getAge());
}

Collections.sort - I have created 2 user define objects [both are of different types] and then add into arraylist , then I have tried to sort it

Expected Result of code is ClassCastException but Actual Result :- [Person with pid- 1 - a1-name, Person with pid- 2 - c2-name, Sorting.Employee#cdfc9c, Sorting.Employee#1837697]
Person class:
package Sorting;
public class Person implements Comparable<Person> {
private int pid;
private String pname;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
#Override
public String toString() {
return "Person with pid- " + getPid() + " - " + getPname();
}
#Override
public int compareTo(Person p) {
return this.pid - p.pid;
}
}
Employee class:
package Sorting;
public class Employee implements Comparable {
#Override
public int compareTo(Object o) {
return 0;
}
}
SortingofObjects class:
package Sorting;
import java.util.ArrayList;
import java.util.Collections;
public class SortingofObjects {
public static void main(String[] args) {
Person p1 = new Person();
p1.setPid(1);
p1.setPname("a1-name");
Person p2 = new Person();
p2.setPid(2);
p2.setPname("c2-name");
Employee e1 = new Employee();
Employee e2 = new Employee();
ArrayList a = new ArrayList();
a.add(p1);
a.add(p2);
a.add(e1);
a.add(e2);
Collections.sort(a);
System.out.println(a);
}
}
Collections.sort does not call compareTo on every pair in the List, just enough pairs to sort the List. As an example, run this code:
public class Test implements Comparable<Test> {
public static void main(String[] args) {
List<Test> list = new ArrayList<Test>();
list.add(new Test(1));
list.add(new Test(2));
list.add(new Test(3));
list.add(new Test(4));
Collections.sort(list);
}
private final int number;
Test(int number) {
this.number = number;
}
#Override
public int compareTo(Test that) {
System.out.println(this + ".compareTo(" + that + ")");
return 0;
}
#Override
public String toString() {
return "" + number;
}
}
The output is
2.compareTo(1)
3.compareTo(2)
4.compareTo(3)
Since your List is in the order Person, Person, Employee, Employee, the only combination that would throw a ClassCastException, namely
Person.compareTo(Employee)
never occurs. If your List contained an Employee before a Person it would throw an exception.
If it just so happens that the sorting algorithm used only compares Employees to Persons, and not the other way around, then it'll never throw, because Employee.compareTo accepts any Object. You just got lucky, more or less.

Categories