I am doing a simple sch program to add friends, which is to add objects into an arraylist. I followed everything but my method befriend() doesn't seem to work.
When i manually test using the .add() in the main, it works. Where am i doing wrongly?
import java.util.*;
public class NetworkFriends {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Person me = new Person("Aloysius", 1);
ArrayList<Person> myList = new ArrayList<Person>(Arrays.asList(me.getFriendList()));
Person p1 = new Person("Gorgon", 2);
Person p2 = new Person("Eddy", 3);
me.befriend(p1);
for(Person i : myList) {
System.out.println("Name: " + i.getName());
}
}
}
class Person
{
private int id;
private String name;
private ArrayList<Person> friendList;
private static int runningNum = 0;
private static int friendsLimit = 5;
private String degree;
private int degreeNum;
/* Constructor - 1 param */
public Person(String name, int degreeNum)
{
//Implement your code here..
//Initialize all necessary variable(s)
this.name = name;
friendList = new ArrayList<Person>(5);
this.degree = degree;
this.degreeNum = degreeNum;
}
public void befriend(Person p){
//Implement your code here..
ArrayList<Person> anotherList = new ArrayList<Person>(Arrays.asList(p.getFriendList()));
for(Person i : friendList) {
if(!isFriend(this) && friendList.size() < 5) {
friendList.add(p);
anotherList.add(this);
}
else if(!isFriend(this) && friendList.size() == 5) {
System.out.println("Friends limit reached");
}
else {
System.out.println("Already in friend list");
}
}
}
}
public boolean isFriend(Person p){
//Implement your code here..
boolean isItAFriend = true;
for(Person i : friendList) {
if(friendList.contains(p)) {
isItAFriend = true;
}
else {
isItAFriend = false;
}
}
return isItAFriend;
}
The problem is with the foreach loop in your befriend method. You are creating a new Person with the constructor that creates a empty friend list with an initial size of 5, but is still empty.
In your befriend method, you then are looping for each friend in this empty list. So the code within the loop will not be executed and the friend is never added to a list.
I suspect you want to do something like this: (and as this looks like homework I will only give you pseudo-code)
Is the person already a friend
Yes - nothing needs to be done or give feedback and return
No - Continue
Have they reached their friend limit
Yes - display feedback and return
No - Continue
Add the friend
Related
A playlist is considered a repeating playlist if any of the songs contain a reference to a previous song in the playlist. Otherwise, the playlist will end with the last song which points to null.
I need to Implement a function isRepeatingPlaylist that, returns true if a playlist is repeating or false if it is not.
For example, the following code prints "true" as both songs point to each other.
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
first.setNextSong(second);
second.setNextSong(first);
System.out.println(first.isRepeatingPlaylist());
Again, this is not a homework exercise, I am doing coding challenges because when I read theory about programming concepts, I can almost understand, but when faced with writing a program I don't know where to start, or how to apply.
public class Song {
private String name;
private Song nextSong;
public Song(String name) {
this.name = name;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
public boolean isRepeatingPlaylist() {
//throw new UnsupportedOperationException("Waiting to be implemented.");
List<String> list = new ArrayList<String>();
list.add(one);
list.add(two);
list.add(three);
list.add(four);
if list.contains()
return true;
else
return false;
}
public static void main(String[] args) {
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
Song third = new Song("a test");
Song fourth = new Song("survivor");
first.setNextSong(second);
second.setNextSong(first);
System.out.println(first.isRepeatingPlaylist();
}
}
You can loop through the playlist and add every song to a set on condition it is not yet in the set. Once you reach the end of the list your list is not a repeating list. If you find a song which exists already in the set, you have a repeating list.
public boolean isRepeatingList(Song firstSong)
{
Set<Song> uniqueSongs=new HashSet<>();
uniqueSongs.add(firstSong);
Song current=firstSong;
while(current.getNextSong()!=null)
{
if(uniqueSongs.contains(current.getNextSong()))
return true;
// add the song to the set, and assign current to the next song
uniqueSongs.add(current=current.getNextSong());
}
// we reached the end of the list without finding any doubles, so:
return false;
}
Please check the answer below:
public boolean isRepeatingPlaylist() {
Song slow = this.nextSong;
Song fast = slow == null ? null : slow.nextSong;
while (fast != null) {
if (slow == this || slow == fast)
return true;
slow = slow.nextSong;
fast = fast.nextSong;
if (fast != null)
fast = fast.nextSong;
}
return false;
}
I think this might work:
public boolean isRepeatingPlaylist()
{
Set<Song> songs = new HashSet<Song>();
songs.add(this);
Song current = this.getNextSong();
//if you did not implment a getter for the nextSong property I think you should
while (current.getNextSong() != null && !songs.contains(current.getNextsong())) {
songs.add(current);
current = current.getNextSong();
}
return songs.contains(current.getNextsong());
}
Edit 1: As mentioned in the comments of this answer, the == in some cases might not be the best because it compares the memory location of each object. In order to fix this issue, implementing the methods hashCode() and equals() are recommended, if you don't know what they are, try reading this.
This problem can be consider the classic problem: linked list has a circle or not.You can find method from here to solve but for your it's not easy to construct linked list,we use another method to solve this problem:count the nextSong,code like this:
public static boolean isRepeatingPlaylist(List<Song> songs) {
int counts = 0;
for (Song song : songs) {
if (null !=song.getNextSong()){
counts ++;
}
}
return songs.size() - counts != 1;
}
The issue with most answers ( esp. one by Conffusion ) is that its not talking about hasCode() & equals(...) method for Song class even though approach is correct. uniqueSongs.contains will not give correct result if these two methods are not properly implemented.
OP has also not shown structure of Song class.
Second thing in code samples of OP is that which class should have which responsibility is not clear & if I already have a custom linkedlist then Java ArrayList won't be needed - though I have added both versions. Use of words - array & arrayList in question title is confusing because OP has a traditional LinkedList & that has noting to do with Java while arrayList is a Java specific DS.
public class Song {
private String data;
private Song nextSong;
public Song(String data) {
this.data=data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Song getNextSong() {
return nextSong;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Song other = (Song) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data)) {
return false;
}
return true;
}
}
Ideally , there should be a PlayList class to create playlist and method isRepeatingPlaylist should belong there. I have added in main driver class for simplicity ,
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RepetablePlaylist {
public static void main(String[] args) {
// Begin - construct Song list
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
Song third = new Song("a test");
Song fourth = new Song("survivor");
first.setNextSong(second);
second.setNextSong(first);
List<Song> list = new ArrayList<>();
list.add(first);
list.add(second);
list.add(third);
list.add(fourth);
// End - construct Song list
boolean isRepeatable = isRepeatingPlaylist(list);
System.out.println(" isRepeatable : "+isRepeatable);
isRepeatable = isRepeatingPlaylist(first);
System.out.println(" isRepeatable : "+isRepeatable);
}
private static boolean isRepeatingPlaylist(List<Song> playList) {
Set<Song> previous = new HashSet<>();
for(Song song : playList) {
if(song.getNextSong() != null && previous.contains(song.getNextSong())) {
return true;
}
previous.add(song);
}
return false;
}
private static boolean isRepeatingPlaylist(Song head) {
Set<Song> previous = new HashSet<>();
Song currentNode = head;
while(currentNode.getNextSong() != null ) {
if(previous.contains(currentNode.getNextSong())) {
return true;
}
previous.add(currentNode);
currentNode=currentNode.getNextSong();
}
return false;
}
}
I used this code, it will work but the site tells that it is not correct.
Is it ok to add another int member to the class?
public class Song {
private String name;
private Song nextSong;
private int rep = 0 ;
public Song(String name) {
this.name = name;
}
public void setNextSong(Song nextSong) {
this.nextSong = nextSong;
}
public boolean isRepeatingPlaylist() {
if (this.nextSong == null){
return false;
} else {
rep++;
if (rep > 1){
return true;
}
return this.nextSong.isRepeatingPlaylist();
}
}
public static void main(String[] args) {
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
first.setNextSong(second );
second.setNextSong(first );
System.out.println(first.isRepeatingPlaylist());
}
}
Please check the answer below:
using System.Collections.Generic;
public bool IsRepeatingPlaylist()
{
HashSet<Song> songs = new HashSet<Song>();
Song current = this;
while (current.NextSong != null && !songs.Contains(current.NextSong))
{
songs.Add(current);
current = current.NextSong;
}
return songs.Contains(current.NextSong);
}
This is my c++ code, it runs greatly!
#include <stdexcept>
#include <iostream>
#include <string>
#include <set>
using namespace std;
class Song
{
public:
Song(std::string name): name(name), nextSong(NULL) {}
void next(Song* song)
{
this->nextSong = song;
}
bool isRepeatingPlaylist()
{
set<string> playlist;
Song *temp=this;
while(temp->nextSong!=NULL){
if (!playlist.insert(temp->name).second) return true;
temp=temp->nextSong;
}
return false;
}
private:
const std::string name;
Song* nextSong;
};
#ifndef RunTests
int main()
{
Song* first = new Song("Hello");
Song* second = new Song("Eye of the tiger");
first->next(second);
second->next(first);
std::cout << std::boolalpha << first->isRepeatingPlaylist();
}
#endif */
As you will probably see from my code I'm quite new with this. I am trying to write a simple program to retrieve the friends of one person. Here is my code:
public class Person {
private String name;
private String friends;
public Person(String aName) {
name = aName;
friends = "";
}
public String getFriends() {
return friends;
}
public void addFriend(Person friend) {
friends = friends + " " + friend.name;
}
public void unfriend(Person nonFriend) {
friends = friends.replace(" " + nonFriend.name, "");
}
public static void main(String[] args) {
Person dana = new Person("Dana");
Person gina = new Person("Gina");
Person john = new Person("John");
dana.addFriend(gina);
dana.addFriend(john);
john.addFriend(gina);
john.addFriend(dana);
john.unfriend(dana);
System.out.println("Dana's friends are: " + dana.getFriends());
System.out.println("Gina's friends are: " + gina.getFriends());
System.out.println("John's friends are: " + john.getFriends());
}
}
Everything works, but I do not know how to create a method that will say:
If Gina is both Dana's and John's friend then clearly Gina's friends will be Dana and John. I know that I can add two lines there gina.addFriend(dana) and gina.addFriend(john), to accomplish the same result, but I would like to know what will the method be for that. Thanks in advance.
First of all, make friends an ArrayList<Friend>.
private ArrayList<Friend> friends;
This has several advantages, including being easier to use and storing the Persons themselves rather than just their names.
Then, change the addFriend method to go in both directions:
public void addFriend(Person friend) {
friends.add(friend);
friend.friends.add(this);
}
In this way, friendships will automatically go back and forth. You should also change unfriend:
public void unFriend(Person friend) {
friends.remove(friend);
friend.friends.remove(this);
}
EDIT: as per a comment above, a set would actually be better, as it can only have one of each value.
I would use a Set, and add a unique Id to person to get around the problem of multiple people having the same name.
Your class will then look like:
public class Person
{
private final String personId;
private final String name;
private final Set<Person> friends;
public Person(String personId, String name) {
super();
this.personId = personId;
this.name = name;
this.friends = new HashSet<Person>();
}
public void addFriend(Person friend) {
if(friend != null && !friends.contains(friend)) {
this.friends.add(friend);
// Optional : if it is a two-way relationship that doesn't need approving etc
friend.addFriend(this);
}
}
public void unfriend(Person nonFriend)
{
if(nonFriend != null && friends.contains(nonFriend)) {
this.friends.remove(nonFriend);
// Optional : if it is a two-way relationship that doesn't need approving etc
nonFriend.unfriend(this);
}
}
public Set<Person> getFriends()
{
return friends;
}
#Override
public String toString() {
return "Person [name=" + name + "]";
}
public static void main(String[] args)
{
Person dana = new Person("D001", "Dana");
Person gina = new Person("G001", "Gina");
Person john = new Person("J001", "John");
dana.addFriend(gina);
dana.addFriend(john);
john.addFriend(gina);
john.addFriend(dana);
john.unfriend(dana);
System.out.println("Dana's friends are: "+dana.getFriends());
System.out.println("Gina's friends are: "+gina.getFriends());
System.out.println("John's friends are: "+john.getFriends());
}
// Equals and Hashcode are very important when using 'contains' and other Set-based methods
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((personId == null) ? 0 : personId.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (personId == null) {
if (other.personId != null)
return false;
} else if (!personId.equals(other.personId))
return false;
return true;
}
}
i would suggest to use an arrayList of persons/friends instead of one string.
ArrayList<Person> friends = new ArrayList<Person>;
you add friends by typing:
public void addFriend(Person newFriend){
friends.add(newFriend);
newFriend.friends.add(this);
}
you delete friends by typing:
public void unfriend(Person noFriend){
for(int i = 0; i < this.friends.size(); i++){
if(this.friends.get(i).name.equals(noFriend.name){
this.friends.delete(i);
}
}
for(int i = 0; i < noFriend.friends.size(); i++){
if(noFriend.friends.get(i).name.equals(this.name){
noFriend.friends.delete(i);
}
}
}
to show the whole list of friends:
public void showFriends(){
for(int i = 0; i < this.friends.size(); i++){
System.out.println(this.friends.get(i));
}
}
I am trying to add objects to my ArrayList friends... I get this error,
The method add(int, Person) in the type ArrayList is not
applicable for the arguments (int, String)
I am trying to add a few instances of my person object to eventually create a tree of friends.
import java.util.*;
public class Person
{
public int id; // some identification number unique to the person
public boolean zombie; // true if the person is a zombie
public char state; // p means human, z means zombie
public static ArrayList<Person> friends; // list of friends
public Person(int id, char state)
{
this.id = id;
this.state = state;
//this.zombie = zombie;
}
public static void addPeople()
{
friends = new ArrayList<Person>();
friends.add(1, 'p');
}
public boolean isZombie()
{
if (state == 'p')
{
return zombie=false;
}
else if (state == 'z')
{
return zombie=true;
}
return zombie;
}
}
The error is located under the "add" word. I would also like to know how I can name the instances of the object so I only call the name rather than the two attributes.
Thanks in advance for all help.
import java.util.ArrayList;
import java.util.List;
/**
* Person description here
* #author Michael
* #link http://stackoverflow.com/questions/15799429/why-am-i-getting-this-error-when-adding-object-to-arraylist-java/15799474?noredirect=1#comment22468741_15799474
* #since 4/3/13 9:45 PM
*/
public class Person {
private Integer id;
private boolean zombie;
private List<Person> friends;
public static void main(String [] args) {
List<Person> lastPeopleStanding = new ArrayList<Person>();
for (int i = 0; i < 3; ++i) {
lastPeopleStanding.add(new Person(i));
}
lastPeopleStanding.get(0).addFriend(lastPeopleStanding.get(1));
lastPeopleStanding.get(0).addFriend(lastPeopleStanding.get(2));
System.out.println(lastPeopleStanding);
}
public Person(Integer id) {
this.id = id;
this.zombie = false;
this.friends = new ArrayList<Person>();
}
public boolean isZombie() { return this.zombie; }
// Irreversible! Once you go zombie, you don't go back
public void turnToZombie() { this.zombie = true; }
// Only add a friend if they're not a zombie
public void addFriend(Person p) {
if (p != null && !p.isZombie()) {
this.friends.add(p);
}
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Person{");
sb.append("id=").append(id);
sb.append(", zombie=").append(zombie);
sb.append(", friends=").append(friends);
sb.append('}');
return sb.toString();
}
}
You forgot to create a new Person to add to your ArrayList:
From your comment, you can create a class member variable called idCount and increment when a Person is added:
public void addPeople() {
friends.add(new Person(++idCount, 'p'));
}
Using static methods is generally considered poor design for a class that can have state.
Sorry if i'm being vague here, i'll post my code for you guys too. I'm a beginner so go easy on me.
I have a class called student, it has an int id, and another String name. I have created another Class for the GUI. It has a window that pops up and has a field for the id. I want to enter the ID and get the Name from that ID. I have no idea of going about this and i've been stuck for hours. I'm kind of slow to catch on, so could someone help me? I'm not very good at inheritance. (also, i have two other classes, but i don't think they would be of any help here.
STUDENT CLASS
public class Student {
private int id;
private String name;
private ArrayList<Course> regCourses;
public int getId() {
return id;
}
public String getName() {
return name;
}
public ArrayList<Course> getRegCourses() {
return regCourses;
}
public Student(int i, String n) {
id = i;
name = n;
regCourses = new ArrayList<Course>();
}
public String toString() {
String answer = id + " " + name + " - Registered Courses: ";
if (regCourses.size() == 0)
answer += "NONE";
else {
for (int i = 0; i < regCourses.size(); i++) {
answer += regCourses.get(i).getDepartment().getId()
+ regCourses.get(i).getCode();
if (i != regCourses.size() - 1)
answer += ", ";
}
}
return answer;
}
public void registerFor(Course c) {
if (!isRegisteredInCourse(c)) {
// Register
regCourses.add(c);
if (!c.getClassList().contains(this)) {
c.getClassList().add(this);
if (!c.getDepartment().getStudentList().contains(this))
c.getDepartment().getStudentList().add(this);
}
}
}
public boolean isRegisteredInCourse(Course c) {
return regCourses.contains(c);
}
}
And here's the search code in another class.
public class MainGUIWindow extends JFrame implements ActionListener {
JLabel studentID, studentName, currentRegCourses;
JButton search, regForCourse, withdraw;
JTextField idField, nameField;
JScrollPane courseScrollList;
public MainGUIWindow(String title) {
super(title);
//GUI STUFF
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == search) {
if (idField.getText() != null) {
int id = Integer.parseInt(idField.getText());
Student temp = null;
//CODE GOES HERE
}
}
}
public static void main(String[] args) {
new MainGUIWindow("Student Administration System").setVisible(true);
Also, if need be, these all my java files.
http://www.filehosting.org/file/details/426633/JavaCode-SO.zip
Edit: There are 2 more Classes that are my test programs that have data in them.
You could store the Students in a Hashmap or treemap and then look them up
i.e
HashMap<Integer,Student> studentMap = new HashMap<>();
studentMap.put(matt.getId(), matt);
.....
Student s = studentMap.get(lookupId); /* Retrieve based on Student id*/
I have some classes and I'm trying to fill the objects of this class. Here is what i've tried. (Question is at the below)
public class Team
{
private String clubName;
private String preName;
private ArrayList<String> branches;
public Team(String clubName, String preName)
{
this.clubName = clubName;
this.preName = preName;
branches = new ArrayList<String>();
}
public Team() {
// TODO Auto-generated constructor stub
}
public String getClubName() { return clubName; }
public String getPreName() { return preName; }
public ArrayList<String> getBranches() { return branches; }
public void setClubName(String clubName) { this.clubName = clubName; }
public void setPreName(String preName) { this.preName = preName; }
public void setBranches(ArrayList<String> branches) { this.branches = branches; }
}
public class Branch
{
private ArrayList<Player> players = new ArrayList<Player>();
String brName;
public Branch() {}
public void setBr(String brName){this.brName = brName;}
public String getBr(){return brName;}
public ArrayList<Player> getPlayers() { return players; }
public void setPlayers(ArrayList<Player> players) { this.players = players; }
}
//TEST CLASS
public class test {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
String a,b,c;
String q = "q";
int brCount = 0, tCount = 0;
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
Team[] teams = new Team[30];
Branch[] myBranch = new Branch[30];
for(int z = 0 ; z <30 ;z++)
{
teams[z] = new Team();
myBranch[z] = new Branch();
}
ArrayList<String> tmp = new ArrayList<String>();
int k = 0;
int secim = Integer.parseInt(input.readLine());
while(secim != 0)
{
if(k!=0)
secim = Integer.parseInt(input.readLine());
k++;
switch(secim)
{
case 1 :
brCount = 0;
a = input.readLine();
teams[tCount].setClubName(a);
b= input.readLine();
teams[tCount].setPreName(b);
c = input.readLine();
while(c.equals(q) == false)
{
if(brCount != 0)
{c = input.readLine();}
if(c.equals(q)== false){
myBranch[brCount].brName = c;
tmp.add(myBranch[brCount].brName);
brCount++;
}
System.out.println(brCount);
}
teams[tCount].setBranches(tmp);
for(int i=0;i<=tCount;i++ ){
System.out.print("a :" + teams[i].getClubName()+ " " + teams[i].getPreName()+ " ");
System.out.println(teams[i].getBranches());}
tCount++;
break;
case 2:
String src = input.readLine();//LATERRRRRRRr
}
}
}
}
The problem is one of my class elements. I have an arraylist as an element of a class.
When i enter:
AAA as preName
BBB as clubName
c
d
e as Branches
Then as a second element
www as preName
GGG as clubName
a
b as branches
The result is coming like:
AAA BBB c,d,e,a,b
GGG www c,d,e,a,b
Which means ArrayList part of the class is putting it on and on. I tried to use clear() method but caused problems. Any ideas.
The problem is that the two Team objects are sharing the same reference to a single ArrayList<String>. There are many ways to solve this, but one way is to let Team manage its own List<Branch>, and it should only expose an add(Branch) instead of setBranches(List<Branch>). This would hide most information from the client, exposing only the most essential functionalities, which is a good thing.
Note also that I use the interface List<Branch> instead of ArrayList<Branch> (or ArrayList<String>). This is in accordance with Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces.
I also recommend using java.util.Scanner for the I/O. Look at the API for examples, and there are many questions on stackoverflow about it as well. It'd make the code much simpler.
You need to copy lists in setters, otherwise you are using the same list (tmp) everywhere, so no wonder it has the same contents:
public void setBranches(List<String> branches) {
this.branches = new ArrayList<String>(branches);
}
public void setPlayers(List<Player> players) {
this.players = new ArrayList<Player>(players);
}
Theoretically, you also need to copy or wrap it in getters, but that's another story.