/* (C) 2024 YourCompanyName */
package design;
import java.util.*;
/**
* Created by gouthamvidyapradhan on 18/03/2017. Design a simplified version of Twitter where users
* can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the
* user's news feed. Your design should support the following methods:
*
*
postTweet(userId, tweetId): Compose a new tweet. getNewsFeed(userId): Retrieve the 10 most
* recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who
* the user followed or by the user herself. Tweets must be ordered from most recent to least
* recent. follow(followerId, followeeId): Follower follows a followee. unfollow(followerId,
* followeeId): Follower unfollows a followee. Example:
*
*
Twitter twitter = new Twitter();
*
*
// User 1 posts a new tweet (id = 5). twitter.postTweet(1, 5);
*
*
// User 1's news feed should return a list with 1 tweet id -> [5]. twitter.getNewsFeed(1);
*
*
// User 1 follows user 2. twitter.follow(1, 2);
*
*
// User 2 posts a new tweet (id = 6). twitter.postTweet(2, 6);
*
*
// User 1's news feed should return a list with 2 tweet ids -> [6, 5]. // Tweet id 6 should
* precede tweet id 5 because it is posted after tweet id 5. twitter.getNewsFeed(1);
*
*
// User 1 unfollows user 2. twitter.unfollow(1, 2);
*
*
// User 1's news feed should return a list with 1 tweet id -> [5], // since user 1 is no
* longer following user 2. twitter.getNewsFeed(1);
*/
public class Twitter {
class User {
int id;
Set follow = new HashSet<>();
Queue tweets = new ArrayDeque<>();
User(int id) {
this.id = id;
}
public void follow(int id) {
follow.add(id);
}
public void addTweet(Tweet t) {
if (tweets.size() == 10) {
tweets.poll();
}
tweets.offer(t);
}
public void unFollow(int id) {
follow.remove(id);
}
public Set getFollow() {
return follow;
}
public Queue getTweets() {
return tweets;
}
}
class Tweet {
int id;
long time;
Tweet(int id, long time) {
this.id = id;
this.time = time;
}
}
private Map userMap;
private Map tweetMap;
private static long tweetCount = 0L;
/**
* Main method
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Twitter twitter = new Twitter();
twitter.postTweet(1, 5);
twitter.follow(1, 1);
System.out.println(twitter.getNewsFeed(1));
/*twitter.follow(2, 1);
System.out.println(twitter.getNewsFeed(2));
//twitter.unfollow(2, 1);
twitter.postTweet(2, 3);
System.out.println(twitter.getNewsFeed(1));
System.out.println(twitter.getNewsFeed(2));
twitter.follow(1, 2);
System.out.println(twitter.getNewsFeed(1));
twitter.unfollow(2, 1);
System.out.println(twitter.getNewsFeed(2));
System.out.println(twitter.getNewsFeed(1));
//twitter.getNewsFeed(2);
*/
}
/** Initialize your data structure here. */
public Twitter() {
userMap = new HashMap<>();
tweetMap = new HashMap<>();
}
/** Compose a new tweet. */
public void postTweet(int userId, int tweetId) {
User user = userMap.get(userId);
if (user == null) {
user = new User(userId);
userMap.put(userId, user);
}
user.addTweet(new Tweet(tweetId, tweetCount++));
}
/**
* Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must
* be posted by users who the user followed or by the user herself. Tweets must be ordered from
* most recent to least recent.
*/
public List getNewsFeed(int userId) {
User user = userMap.get(userId);
List result = new ArrayList<>();
if (user == null) return result;
Set follwers = user.getFollow();
if (follwers != null) {
List tweets = new ArrayList<>();
tweets.addAll(user.getTweets());
for (Integer i : follwers) {
User f = userMap.get(i);
if (f != null) {
tweets.addAll(f.getTweets());
}
}
Comparator comparator =
new Comparator() {
@Override
public int compare(Tweet o1, Tweet o2) {
return Long.compare(o2.time, o1.time);
}
};
Collections.sort(tweets, comparator);
for (int i = 0; i < 10; i++) {
if (i >= tweets.size()) break;
result.add(tweets.get(i).id);
}
}
return result;
}
/** Follower follows a followee. If the operation is invalid, it should be a no-op. */
public void follow(int followerId, int followeeId) {
if (followerId == followeeId) return;
User user = userMap.get(followerId);
if (user == null) user = new User(followerId);
userMap.put(followerId, user);
if (userMap.get(followeeId) != null) {
user.follow(userMap.get(followeeId).id);
} else {
User newUser = new User(followeeId);
userMap.put(followeeId, newUser);
user.follow(userMap.get(followeeId).id);
}
}
/** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
public void unfollow(int followerId, int followeeId) {
User user = userMap.get(followerId);
if (user != null) {
user.unFollow(followeeId);
}
}
}