Adding Objects to an ArrayList without error - java

I am just trying to add some objects to an ArrayList in eclipse, but i keept getting an error (Syntax error, insert "... VariableDeclaratorId" to complete FormalParameterList) under the 'persons.add(one);'. Any idea what I am doing wrong?
package thequestion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class PersonComparator implements Comparator<Person>{
#Override
public int compare(Person o1, Person o2) {
return 0;
}
Person one = new Person("Kevin", "Gresmer");
List<Person> persons = new ArrayList<Person>();
persons.add(one);
public void sortByLastName(List people) {
Comparator comp = new PersonComparator();
Collections.sort(people, comp);
}
}
public class Person {
private String firstName = null;
private String lastName = null;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

The line persons.add(one) is a statement, and you can't have a statement outside a block of code (method, constructor, etc.). Also, your Comparator should contain code related to the comparison you are doing. I don't think it's the right place to store a list or implement the sortByLastName() method.

You can only initialize the instance variables in class and outside the methods.
You initialized persons. Then to apply methods, you need to put that line into some methods. So, may be you can update your Sort Method or create new one and make reference to that method from your sort method.
The first option as explained in the above comment.
class PersonComparator implements Comparator{
#Override
public int compare(Person o1, Person o2) {
return 0;
}
Person one = new Person("Kevin", "Gresmer");
List<Person> persons = new ArrayList<Person>();
private void addPersons(){
persons.add(one);
}
//persons.add(one);
public void sortByLastName(List people) {
addPersons();
Comparator comp = new PersonComparator();
Collections.sort(people, comp);
}
}
The point is we cannot write anything except the Instance variables. We have to cover them with methods. I hope this will solve your issue.

put below under sortByLastName method. Currently below code snippet not lying under any method.
persons.add(one);
Correct code should be
public void sortByLastName(List people) {
persons.add(one);
Comparator comp = new PersonComparator();
Collections.sort(persons , comp);
}
please note :- But my answer is in terms of compilation error. Ideally comparator should have code only related to comparison. Nothing else.

Obviously, you cannot do persons.add(...) in the middle of the class declaration.
You should certainly add one and persons in a main in the class Person, and keep your Comparator class clean with only the logic of comparison. The main will allow you to test your code.
The same idea for the sortByLastName(...) you can declare it as static in Person class.
Then you can test with the main, e.g.
// In class `Person`
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();
Person one = new Person("Kevin", "Gresmer");
persons.add(one);
Person two = new Person("Elvis", "Presley");
persons.add(two);
System.out.println(sortByLastName(persons));
}
Note for the above to provide a sensible output, you need to add a toString() method to the Person class.

Related

Adding an object to an array in a separate class

edit:
I am looking to pass HomeBuyers Objects to my homeBuyers ArrayList in my CreditUnion class. The this.homeBuyers.add function throws a "cannot find symbol" error. I have tried making the firstName, lastName, and creditScore vars static and passing the object in with HomeBuyers(HomeBuyers.firstName, HomeBuyers.lastName, HomeBuyers.creditScore). That avoided errors but did not add the object to the ArrayList.
public class LabProgram {
public static void main(String[] args) {
CreditUnion cu = new CreditUnion();
cu.addHomeBuyer(new HomeBuyers("first","last",600));
}
}
public class HomeBuyers {
public String firstName;
public String lastName;
public int creditScore;
public HomeBuyers(String firstName, String lastName, int creditScore) {
this.firstName = firstName;
this.lastName = lastName;
this.creditScore = creditScore;
}
}
public class CreditUnion {
public ArrayList<HomeBuyers> homeBuyers;
public CreditUnion() {
this.homeBuyers = new ArrayList<>();
}
public void addHomeBuyer(HomeBuyers homeBuyers) {
this.homeBuyers.add(HomeBuyers(firstName, lastName, creditScore));
}
You have multiple problems here.
The right syntax for creating a new object is new HomeBuyers(...). Not HomeBuyers().
Separately, firstName doesn't exist as a variable in your addHomeBuyer method. The only variable that does exist is homeBuyers. You could write homeBuyers.firstName. However, you already have an instance of your class HomeBuyers. There is no need to make another one with identical values. this.homeBuyers.add(homeBuyers) would have done the job.
These questions are incredibly simplistic; stack overflow probably isn't the right venue. I suggest any of the many nice tutorials out there, they tend to take a little more time to explain things in an orderly fashion.

impose order (not sorting) using comparator on a wrapper class of a list in Java

I have a class, person. it has Age, Name, Height, etc.
I am creating a class called PersonCollection which is a wrapper of a list (an ArrayList).
I will like to be able to compare Person objects using the PersonCollection class, Which means, I don't want to make the Person class implement the Comparable interface, I would like the PersonCollection to implement the Comparator interface.
I have having trouble doing that. I have implemented the compare method but still when I compare Person Objects it doesn't work.
for example this code gives me an error (people is an ArrayList
public void insert (Person p){
for(int i = 0; i < people.size(); i++){
if (people.get(i) > p){
//Do something
}
}
}
I know how to use Comparator for sorting, this is different.
I am fully aware of other possible and maybe better solutions (any priority queue class or some sort of sortedset classes)
I wish to do that for ArrayList for a specific reason and I kindly ask you to base your solutions on this instead of suggest other Data structures.
You can write a custom Comparator and use the compare(a, b) method.
https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-
Your code would look like
if (myComparator.compare(people.get(i), p) > 0 ) {
According to your description you have a Wrapper class like this?
public class People implements List<Person>, Comparator<Person>{
/* methods */
}
so if you want to really use comparator interface, then you would have to do it like this:
public void insert (Person p){
for(int i = 0; i < people.size(); i++){
if (people.compare(people.get(i),p)){ // because people implements Comparator
//Do something
}
}
}
which should (not too sure though) work.
But i would highly recommend not to use this and think about something better, as a class should not be a comparator and a list (because both interfaces should be used for completly different reasons).
A better approach would be to make Person implement Comparable, and then sort according to that
Below is a piece of code where you can see a custom comparator is making an age comparison on Person object's age attribute.
public class TestCompare {
public static void main(String[] args) {
Person person1 = new Person(45, "Tom");
Person person2 = new Person(12, "Sarah");
Person person3 = new Person(34, "Michael");
Person person4 = new Person(33, "Donald");
Person person5 = new Person(65, "timothy");
List<Person> people = new ArrayList<Person>();
people.add(person1);
people.add(person2);
people.add(person3);
people.add(person4);
people.add(person5);
CustomComparator comparator=new CustomComparator();
for (Person p : people) {
System.out.println(comparator.compare(p, new Person(55, "James")));
}
}
}
class CustomComparator implements Comparator<Person> {
#Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return o1.getAge().compareTo(o2.getAge());
}
}
class Person implements Comparable<Person> {
public Person(int age, String name) {
this.age = age;
this.name = name;
}
private Integer age;
private String name;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return this.getAge().compareTo(o.getAge());
}
}

creating map of values from object

we have
class Student
{
String name,
int age,
String specialization
}
and
class Students
{
List<String> names,
List<Integer> age,
List<String> specialization
}
Students object is basically a structure that holds field values of Student class,
What is the best way to fill Students object without using reflection.
Edit: we have a specific requirement of having Students class as it is, the reason for this is we don't always want all the information in Student class and if we have List it would allocate memory for the fields that we are not interested in.
Don't create class Students. Hold a list of Student
List<Student> students = new ArrayList<Student>();
And to access a student data you can use
students.get(0).name;
As a side note, you should learn about getters and setters.
I wouldn't recommend creating a class named "Students" for this purpose. Your intention is to create a collection to hold the Student objects.
In this case, do the following:
List<Student> students = new ArrayList();
Also, pay attention to the capitalization: class is a keyword and should be spelled all lower-case.
EDIT After seeing a comment from venkat:
If you really need to create a class called Students then following should work (also similar answer provided above by another SO user):
class Students {
List<Student> students = new ArrayList();
}
This should work, but I would highly recommend not to use these type of class with the plural names!
PS: I am a CS prof teaching programming languages in a university and a long time developer/consultant.
Class Students {
List<Student> students;
}
Maybe you want to use a Decorator-Pattern (I don't think that i saves memory):
Implement a base class with the default field:
public class BaseClass implements INameGettable {
protected String name;
public BaseClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Add the default interface:
public interface INameGettable {
String getName();
}
Add a decorator to for an additional field e.g. age:
public class Decorator implements INameGettable {
protected INameGettable nameable;
protected int age;
public Decorator(INameGettable nameable, int age) {
this.nameable = nameable;
this.age = age;
}
public String getName() {
return nameable.getName();
}
public int getAge() {
return this.age;
}
}
Usage:
// First object contains only name
INameable namegettable = new BaseClass("Test1");
namegettable.getName();
// Second object contains name and age
Decorator agegettable = new Decorator(new BaseClass("Test2"), 77);
agegettable.getName();
agegettable.getAge();
Going for the obvious answer here.
class Students
{
List<String> names;
List<Integer> age;
List<String> specialization;
public Student(List<Student> students) {
addStudents(students);
}
private void addStudents(List<Student> students) {
names = students.stream
.map(Student::getName)
.collect(Collectors.toList())
age = students.stream
.map(Student::getAge)
.collect(Collectors.toList())
specialization = students.stream
.map(Student::getSpecialization)
.collect(Collectors.toList())
}
}

Automatic constructor matching in default method

I have a PersonFactory interface as follows:
#FunctionalInterface
public interface PersonFactory<P extends Person> {
P create(String firstname, String lastname);
// Return a person with no args
default P create() {
// Is there a way I could make this work?
}
}
The Person class:
public class Person {
public String firstname;
public String lastname;
public Person() {}
public Person(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
}
I want to be able to instantiate my Persons like this:
PersonFactory<Person> personFactory = Person::new;
Person p = personFactory.create(); // does not work
Person p = personFactory.create("firstname", "lastname"); // works
Is there a way I could make the Java compiler automatically choose the right constructor by matching the signature of PersonFactory.create() ?
One way would be to have the following:
default P create() {
return create(null, null);
}
But I'm not sure that's what you wanted. The problem is that you can't make a method reference refer to 2 different methods (or constructors). In this case, you want Person::new to refer to the constructor taking no parameters and the constructor taking 2 parameters, which is not possible.
When you have:
#FunctionalInterface
public interface PersonFactory<P extends Person> {
P create(String firstname, String lastname);
}
and use it like
PersonFactory<Person> personFactory = Person::new;
Person p = personFactory.create("firstname", "lastname");
you have to realize that the method-reference Person::new refers to the constructor taking 2 parameters. The next line just invokes it by passing the parameters.
You could also write it more explicitely using a lambda expression:
PersonFactory<Person> personFactory = (s1, s2) -> new Person(s1, s2); // see, we have the 2 Strings here
Person p = personFactory.create("firstname", "lastname");

a little programa to create people

I want to make a program to create people and to show a list of such persons, but do not know if I am doing well and neither logic using "arraylist" to print the results anyone can help me? Thank you very much.
package person;
import java.util.*;
public class Person {
public int Id;
public String Name;
public boolean Show;
public ArrayList people;
public Person(
int identificator,
String thename,
boolean showornot
){
this.Id = identificator;
this.Name = thename;
this.Show = showornot;
}
public void InsertPerson(Person person, ArrayList list){
this.people = list;
list.add(person);
}
}
The main:
package person;
import java.util.*;
public class Trying {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
Scanner stdin2 = new Scanner(System.in);
Scanner stdin3 = new Scanner(System.in);
Scanner stdin4 = new Scanner(System.in);
ArrayList list_of_people;
list_of_people = new ArrayList();
int option = 0;
int identificador = 0;
String name = "";
boolean show = true;
name = “Toni”;
Person person1 = new Person(identificador, name, true);
person1.InsertPerson (person1, list_of_people);
Iterator ite = list_of_people.iterator();
while(ite.hasNext()){
System.out.println(list_of_people);
}
}
Thanks!
Problem: You are creating the arraylist "people" as a property of each "person" (Saying, each person has a list of people)
Quickfix:
Move public ArrayList people; to your Trying class.
Move public void InsertPerson(Person person, ArrayList list) to your Trying class as well.
Better fix:
I recommend using a PeopleManager class - which contains the arraylist "people" and the InsertPerson method. Then, you use the PeopleManager in Trying to build your people list.
public class PersonManager
{
ArrayList<Person> people;
public PersonManager()
{
people = new ArrayList<Person>();
}
public void InsertPerson(Person person)
{
people.add(person);
}
}
Then, you can remove the arraylist from Person, and the method InsertPerson from Person. You'll need to create a PersonManager in your Trying class.
public ArrayList people; does not belong in the Person class. I would suggest using it your client code (the Trying class) or creating a class People that inherits from ArrayList. You can then add a InsertPerson function to that class if you wish.
I would also suggest using a ArrayList for your collection rather than an ArrayList. See a generic collections tutorial here. You should also create getter/setter moethods instead of using public fields.
So, your classes would be:
public class Person { // ...
public class People extends ArrayList<Person> {
public void InsertPerson(Person person) {
this.add(person);
}
// ...
What everyone else is saying is true, but I think theoretically your code should still work. There is a problem with this line however...
while(ite.hasNext()){
System.out.println(list_of_people);
}
You are outputting the whole list every iteration and probably infinite looping. Change it to something like this...
while(ite.hasNext()){
Person curPerson = (Person)ite.next();
System.out.println(curPerson.Name);
}
A slightly more elegant solution is to ditch the iterator for a foreach loop...
for (Person person : list_of_people) {
System.out.println(person.Name);
}

Categories

Resources