I'm trying to create a Person class which has getName() method, addFriend(Person R) method, ArrayList<Person> getFriendList()
String Name;
private ArrayList Person friend = new ArrayList Person ();
public Person(String name)
{
this.Name=name;
}
public ArrayList<Person> getFriendList(){
return friend;
}
public void addFriend(Person R){
friend.add(R);
}
FriendsOfFriends(){
//list of friends of friends of this person.
}
public static int (p,q){
//return the number of friends shared by both R and q.
}
public static int numberOfMutualFriends(Person p, Person q){
//return the number of friends shared by both R and q.
return intersection(p.friend,q.friend).size();
}
public List<Person> intersection(List<Person> list1, List<Person> list2) {
List<Person> list = new ArrayList<Person>();
for (Person t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
You'll need to redefine the hashCode and the equals method in order to make it work.
Seems you're studying bulk operations on collections.
To get friends of friends, use Set#addAll() in the for-each loop:
List<Person> getFriendsOfFriends() {
Set<Person> res = new HashSet<>(); // empty set
for (Person p : this.friends)
res.addAll(p.friends); // add all p's friends
return new ArrayList<>(res); // copy to ArrayList and return
}
To get number of mutual friends, use Set#retainAll():
public static int numberOfMutualFriends(Person p, Person q) {
// set containing friends of p (not to modify p.friends itself)
Set<Person> res = new HashSet<>(p.friends);
res.retainAll(q.friends); // leave only mutual friends
return res.size();
}
This will work if there are no Person clones in data (i. e. every Person is presented as exactly one object). Otherwise, to make it work correctly, you must override .equals() and .hashCode() in Person class.
Related
I made this Student ArrayList that have name, age and number variable. I manually input 3 student. I want to check if a name already exist in my list. I tried to use list.contains but it seems not working. Are there certain way to do for this kind of ArrayList?
public class CompareToeX {
public static void main(String[] args) {
ArrayList<Student> obj=new ArrayList<Student>();
obj.add(new Student("Peter", 27,1));
obj.add(new Student("John",26,7));
obj.add(new Student("Jack",21,5));
if(obj.contains("Peter")){
System.out.println("Peter on is on the list!");
} else {
System.out.println("Peter is not on the list!");
}
}
}
This is the Student class
public class Student{
private String studentName;
private int age;
private int rollno;
public Student(String studentName, int age, int rollno){
this.studentName=studentName;
this.age=age;
this.rollno=rollno;
}
public String getStudent(){
return studentName;
}
public int getAge(){
return age;
}
public int getRollno(){
return rollno;
}
public void setStudent(String Student){
studentName=Student;
}
public void setAge(int age){
this.age=age;
}
public void setRollno(int rollno){
this.rollno=rollno;
}
}
After I run, the result should show that peter is on the list right. But it goes the other way around. It seems that the contains method is not working.
A student isn't a name.
.contains() will fail here because the string "Peter" is not in the list. It obviously isn't; how could it be? This list only contains Student objects, not Strings, after all.
You'll have to write a for loop, or use streams.
boolean peterIsInTheList = false;
for (var s : students) {
if (s.getName().equals("peter")) peterIsInTheList = true;
}
or
boolean peterIsInTheList = students.stream()
.anyMatch(s -> s.getName().equals("peter"));
Alternatively you could use the idea of a map; change your data structure. Instead of using a list, have a map that maps first names onto student objects:
Map<String, Student> students = new HashMap<>();
students.put("peter", new Student(....));
if (students.containsKey("peter")) {
// peter is in the list
}
You are checking if the String Peter is in the list, or the list only contains Student object. So you can only check if Student is contained inside the list (be sure to implement the right equals/hashcode method if you wish to use .contains).
This will do
obj.stream()
.filter(student -> student.getStudent().contains("Peter"))
.findFirst()
.ifPresentOrElse(student -> System.out.println("Peter on is on the list!"), () -> System.out.println("Peter is not on the list!"));
Being not a default data type, I think you need to override some functions of ArrayList first, like the .compare() one.
It was answered here too
Java: to use contains in a ArrayList full of custom object should I override equals or implement Comparable/Comparator?
i have two lists (personList From DB and inputPersonList from UI).
I want to make sure each row in personList find (matches) corresponding row in inputPersonList according to id(without sort)
Person person1=new Person();
Person person2=new Person();
Person person1=new Person();
List<Person> personList=new ArrayList();
List<Person> inputPersonList=new ArrayList();
person1.Id(1);
person1.setName("A");
person1.setFamily("B");
person2.Id(2);
person2.setName("C");
person2.setFamily("D");
person3.Id(3);
person3.setName("E");
person3.setFamily("F");
personList.add(person1);
personList.add(person2);
personList.add(person3);
inputPersonList.add(person1);
inputPersonList.add(person3);
inputPersonList.add(person2);
Assuming your list contains a custom Object. If so just overwrite the compareTo method in your custom Object and then iterate through the List, checking each corresponding element.
For example:
Here is a custom Book object that implements Comparable:
public class Book implements Comparable {
String isbn;
String title;
public Book(String id, String title) {
this.isbn = id;
this.title = title;
}
String getIsbn() {
return isbn;
}
String getTitle() {
return title;
}
#Override
public int compareTo(Object o) {
return Comparator
.comparing(Book::getIsbn)
.thenComparing(Book::getTitle)
.compare(this, (Book) o);
}
#Override
public String toString() {
String output = new StringBuilder()
.append(isbn).append(":").append(title)
.toString();
return output;
}
}
The following creates two lists (to represent the DB list and the UI lists) and then compares them based on position in the list (namely "corresponding row"):
public void CompareTwoLists(){
List<Book> libraryUI = new ArrayList<>();
libraryUI.add(new Book("9780593098240", "Children of Dune"));
libraryUI.add(new Book("9780593098233", "Dune Messiah"));
libraryUI.add(new Book("9780441172719", "Dune"));
List<Book> libraryDB = new ArrayList<>();
libraryDB.add(new Book("9780593098240", "Children of Dune"));
libraryDB.add(new Book("9780593098233", "Dune Messiah"));
libraryDB.add(new Book("9788886845687", "God Emperor of Dune"));
boolean theSame = Boolean.TRUE;
if(libraryDB.size() != libraryUI.size()) {
theSame = Boolean.FALSE;
} else {
for(int i = 0; i < libraryDB.size(); i++) {
if (libraryDB.get(i).compareTo(libraryUI.get(i)) != 0) {
theSame = Boolean.FALSE;
break;
}
}
}
if(theSame) {
System.out.println("The same");
} else {
System.out.println("Not the same");
}
}
What you can do is check if each of the two lists contains all the elements of the other list and their size is equal:
public static void main(String[] args) throws ParseException {
Person person1 = new Person();
Person person2 = new Person();
Person person3 = new Person();
List<Person> personList = new ArrayList<>();
List<Person> inputPersonList = new ArrayList<>();
person1.Id(1);
person1.setName("A");
person1.setFamily("B");
person2.Id(2);
person2.setName("C");
person2.setFamily("D");
person3.Id(3);
person3.setName("E");
person3.setFamily("F");
personList.add(person1);
personList.add(person2);
personList.add(person3);
inputPersonList.add(person1);
inputPersonList.add(person3);
inputPersonList.add(person2);
// compare the lists using the built-in "equals()" method, which considers order of elements
System.out.println(personList.equals(inputPersonList) ?
"equal (considering order)" : "not equal (considering order)");
// then compare them with the other possibility
System.out.println(areEqual(personList, inputPersonList) ?
"equal (without considering order)" : "not equal (without considering order)");
}
public static boolean areEqual(List<Person> persons, List<Person> personsToo) {
if (persons.containsAll(personsToo) && personsToo.containsAll(persons)
&& persons.size() == personsToo.size()) {
return true;
} else {
return false;
}
}
Keep in mind that this does not consider the case of duplicate elements correctly, because it only checks if an element is present in both lists, not if their count in the lists is equal. You could add person1 a second time to personList and person3 a second time to imputPersonList and the result would still be true respectively equality.
As says Ambro-r you need use the Comparable interface but if you don't have access to the Entity, you should extends Book Class.
public class MyBook extends Book implements Comparable {
#Override
public int compareTo(Object o) {
//compare with other book with the attributes what you want maybe could:
return this.isbn > ((MyBook) o).isbn
}
#Override
public String toString() {
//return super.toString() or your own toString
}
Then you should create lists of MyBook objects.
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());
}
}
I am having my final exam tomorrow so i am practicing some questions.But i am stuck at this question.I am given a person class file and a half completed quiz10 file whereby i have to fill up.The quiz10 codes are halfway done(given).
I need to implement a function findPersonWhoseNameStartWith which returns the names of the persons in the list who start with A. But i have no idea how.
Output wanted:
result:April,Adam
public class Person{
private int age;
private String name;
public Person(String name,int age){
this.name=name;
this.age=age;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String toString(){
return "" + name;
}
}
Half given codes(I have indicate which part i have attempted):
import java.util.*;
public class Quiz10{
public static void main(String[] args){
ArrayList<Person>list=new ArrayList<Person>();
list.add(new Person("April",9));
list.add(new Person("Adam",3));
list.add(new Person("bil",9));
list.add(new Person("cpril",9));
list.add(new Person("dpril",9));
ArrayList<Person>result=findPersonWhoseNameStartWith(list,"A");
System.out.println("result:");
//START DOING FROM HERE
for(int i=0;i<list.size();i++){
Person p=list.get(i);
if(p.findPersonWhoseNameStartWith("A");
}
}
You are on the right track. you are right you have to iterate over the list. Now for each entry output it if it starts with 'A'. It's very simple and a single if statement way easier than what you imagine it seems.
// pass your personList and the prefix, return a list of person starting with the prefix you specified
private List<Person> findPersonWhoseNameStartWith(List<Person> personList, String prefix) {
// create a list to store your result
List<Person> matchedList = new ArrayList<Person>();
// TODO iterate personList
// add them to the matchedList if the prefix matches
return matchedList;
}
public List<Person> findAPersonWhoStartsWith(List<Person> persons, String aLetter){
List<String> personsNames = new ArrayList<String>();
if(persons!=null && aLetter!=null && !aLetter.isEmpty()){
for(Person aPerson:persons){
if(aPerson.getName().startsWith(aLetter)){
personsNames.add(aPerson);
}
}
}
return personsNames;
}
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);
}