I have code I am working on, but I am having issues populating the HashMap of HashMaps. The declaration goes as thus;
HashMap<Games, HashMap<Store, Integer>> myMap = new HashMap<Games, HashMap<Store, Integer>>();
Where Game and Store are separate object classes, with only a class variable title.
How do I create instances of the objects in the HashMaps and also populate the two hashmaps. Because I need to tag an Integer to the game in a particular store. Whereas there are different stores and different games in each store.
Thanks in Advance
Edit
Games Class
package gameStore;
public class Games {
private String title;
public Games(String inTitle){
setTitle(inTitle);
}
private String getTitle() {
return title;
}
private void setTitle(String title) {
this.title = title;
}
}
Stores Class
package gameStore;
public class LocalStores {
private String nameOfStore;
public LocalStores(String inNameOfStore){
setNameOfStore(inNameOfStore);
}
private void setNameOfStore(String nameOfStore){
this.nameOfStore = nameOfStore;
}
}
I would do something like this:
void addToMap(Games games, Store store, int value) {
HashMap<Store,Integer> m = myMap.get(games);
if (m == null) {
m = new HashMap<Store,Integer>();
myMap.put(games, m);
}
m.put(store, value);
}
UPDATE:
Since Games and Store are both used as keys to a HashMap, I would recommand that you add the hashCode and equals methods:
Games:
public int hashCode() {
return title.hashCode();
}
public boolean equals(Object obj) {
if (!(obj instanceof Games)) {
return false;
}
Games other = (Games)obj;
return title.equals(other.title);
}
LocalStores:
public int hashCode() {
return nameOfStore.hashCode();
}
public boolean equals(Object obj) {
if (!(obj instanceof LocalStores)) {
return false;
}
LocalStores other = (LocalStores)obj;
return nameOfStore.equals(other.nameOfStore);
}
Now, to keep it simple, let's say that each line of your input file contains three fields separated by tabs: the games' title, the store's name, and the integer value. You would read it as follows:
InputStream stream = new FileInputStream("myfile");
try {
Reader reader = new InputStreamReader(stream, "UTF-8"); // or another encoding
try {
BufferedInputStream in = new BufferedInputStream(reader);
try {
String line = in.readLine();
while (line != null) {
String[] fields = line.split("[\\t]");
if (fields.length == 3) {
addToMap(new Games(fields[0]), new LocalStores(fields[1]), Integer.parseInt(fields[2]));
}
line = in.readLine();
}
} finally {
in.close();
}
} finally {
reader.close();
}
} finally {
stream.close();
}
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 */
Here's the gist, essentially I have this method right with the exception of one conditional that I just can't seem to get. The condition is that if addGame() is called twice with the same two Strings it will not store the Game object in the games ArrayList since it will return false. I have already attempted to utilize the ArrayList contains() method to fix it, but the JUnit test I created fails each time. Here's the code for the method:
public class Conference {
private ArrayList<Team> teams;
private ArrayList<Player> players;
private ArrayList<Game> games;
public Conference(){
teams = new ArrayList<Team>();
players = new ArrayList<Player>();
games = new ArrayList<Game>();
}
public boolean addGame(String team1, String team2) {
Game tempgame = new Game(team1, team2, 0, 0);
Team first = new Team(team1, 0, 0, 0);
Team second = new Team(team2, 0, 0, 0);
if(!tempgame.getFirst().equals(tempgame.getSecond())){
games.add(tempgame);
first.addGamesPlayed();
second.addGamesPlayed();
teams.add(first);
teams.add(second);
return true;
}
return false;
}
The Game class is as follows:
package conference;
import java.util.ArrayList;
public class Game {
private String firstTeam;
private String secondTeam;
private int firstTeamGoals;
private int secondTeamGoals;
private ArrayList<Team> team;
public Game(String first, String second, int goals1, int goals2){
this.firstTeam = first;
this.secondTeam = second;
this.firstTeamGoals = goals1;
this.secondTeamGoals = goals2;
team = new ArrayList<Team>();
}
public String getFirst(){
return new String(firstTeam);
}
public String getSecond(){
return new String(secondTeam);
}
public int getFirstTeamGoals(){
return this.firstTeamGoals;
}
public int addFirstTeamGoals(){
return firstTeamGoals++;
}
public int getSecondTeamGoals(){
return this.secondTeamGoals;
}
public int addSecondTeamGoals(){
return secondTeamGoals++;
}
public boolean hasMatchup(String t1, String t2){
if(this.firstTeam.equals(t1) && this.secondTeam.equals(t2)){
return true;
}
if(this.firstTeam.equals(t2) && this.secondTeam.equals(t1)){
return true;
}
return false;
}
}
And the Team class:
package conference;
public class Team {
private String teamName;
private int goalsScored;
private int gamesPlayed;
private int gamesWon;
public Team(String name, int totalGoals, int games, int wins){
this.teamName = name;
this.goalsScored = totalGoals;
this.gamesPlayed = games;
this.gamesWon = wins;
}
public String getName(){
return new String(teamName);
}
public int getTotalGoals(){
return goalsScored;
}
public int addGoals(){
return goalsScored++;
}
public int addGamesPlayed(){
return this.gamesPlayed++;
}
public int getGamesPlayed(){
return gamesPlayed;
}
public int addGamesWon(){
return gamesWon++;
}
public int getGamesWon(){
return gamesWon;
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
} else if (obj == this) {
return true;
} else {
if (!(obj instanceof Team)) {
return false;
} else {
Team temp = (Team) obj;
return this.teamName.equals(temp.getName());
}
}
}
}
Your method is likely failing because though the strings aren't equal, that doesn't mean that the teams or games list don't already have those strings. You need to loop over the games list and check if the name equals team1 or team2, if so, return false.
It's good that you compare the given teams aren't the same, and you can use your parameters to compare, but that's not the only condition you need.
if(!team1.equals(team2)) {
Also, the fact you have new String on values that are already strings makes a new object in memory, (therefore it's pointless) but the equals method should still work.
"The strings are stored in a game object, that's why I can't have two of the same objects stored in the ArrayList ever" (Your comment.)
It seems that in exchange for more memory you could use a Set (HashSet or TreeSet) to store records of previous games played. If you're protecting against identical pairings rather than identical team names (at any point), sort the two String team names consistently and concatenate them into a key. Check whether that key already exists in the set.
EDIT: See the other solution for ArrayList only.
I want to sort ArrayList according to artist's name I have used comparator interface but I'm not able to sort the list. So kindly help me to solve the problem. The track data will be read from a file Trackdump. The file would contain one track data per line in the format TITLE/ARTIST/RATING/BPM
Here is the code:
import java.io.*;
import java.util.*;
public class MusicLibrary {
ArrayList<Track> songList = new ArrayList<Track>();
public static void main(String args[]) {
new MusicLibrary().go();
}
public void go() {
System.out.println("go");
getTracks();
System.out.println("Before Sorting:");
System.out.println(songList);
Collections.sort(songList);
System.out.println("Sorted according to Artist's name:");
System.out.println(songList);
}
void getTracks() {
System.out.println("gt");
File file = new File("TrackDump.txt");
try{
BufferedReader readr = new BufferedReader(new FileReader(file));
String line = null;
System.out.println(readr);
while ((line = readr.readLine()) != null) {
System.out.println(line);
addSong(line);
}
}catch(Exception e){
e.printStackTrace();
}
}
void addSong(String lineToParse) {
String[] tokens = lineToParse.split("/");
Track nextSong = new Track(tokens[0], tokens[1], tokens[2], tokens[3]);
songList.add(nextSong);
System.out.println(songList);
}
}
class Track implements Comparator<Track>
{
String title;
String artist;
String rating;
String bpm;
public int compare(Track o1, Track o2) {
return o1.getArtist().compareTo(o2.getArtist());
}
public Track(String a, String t, String r, String b) {
title = t;
artist = a;
rating = r;
bpm = b;
}
public boolean equals(Object aSong) {
return this.equals(aSong);
}
public String getArtist() {
return artist;
}
public String getBpm() {
return bpm;
}
public String getRating() {
return rating;
}
public String getTitle() {
return title;
}
public String toString() {
return title + "-" + artist;
}
}
Trackdump:
Title1/Artist1/8/320
Title2/Artist2/10/48
T5/A7/10/120
Title4/A7/9/240
T7/Artist5/7/320
Title6/Artist6/3/240
T9/A7/1/550
T6/Artist8/5/120
T1/Artist9/5/290
Song2/A0/5/320
Song5/A8/10/320
Song1/A2/6/290
You have to implement Comparable class to your Track class. Not Comparator. Then override compareTo() method. It would look like this:
public class Track implements Comparable<Track> {
// Variables, constructor, getters, setters ...
#Override
public int compareTo(Track other) {
return this.getArtist().compareTo(other.getArtist());
}
}
Finally sort with Collections.sort();
You need to implement the Comparable interface and then you can use Collections.sort().
class Track implements Comparable<Track> {
String title;
String artist;
String rating;
String bpm;
#Override
public int compare(Track other) {
return this.getArtist().compareTo(other.getArtist());
}
...
In theory it would work too when implementing Comparator but then you have to pass a Track object into Collections.sort() to act as the Comparator. But that is a rather weird way of doing it so better use the solution above.
Collections.sort(songList, new Track(null, null, null, null));
I have a project I'm working on and pretty much I need to make an ArrayList of the Abstract Class AbstractCustomer; the ArrayList needs to be made up of AbstractCustomer read in from either a data or text file, so I'm trying to do it through a data file but can't wrap my head around it?
This is my class:
import java.io.FileOutputStream;
import java.io.*;
public abstract class AbstractCustomer implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String phoneNumber;
private final int MIN_LENGTH = 10;
public AbstractCustomer() {
}
public AbstractCustomer(String name, String phoneNumber) {
this.name = name;
this.phoneNumber = phoneNumber;
//Phone number is less than 10, but what if it's more than 10?
//Assignment doesn't say, so I will assume it can be more than 10.
//Ya know country codes 1845 and all that
if (phoneNumber.length() < MIN_LENGTH) {
throw new NumberFormatException("Phone number must be at least 10 digits long.");
}
//Parse the long, so this will rule out anything else except digit.
try {
Long.parseLong(phoneNumber);
} catch (NumberFormatException e) {
System.out.println("Phone number can only contain digits, please no dashes ('-') or spaces (' ')");
}
}
abstract double returnDiscountPrice(double itemCost);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractCustomer other = (AbstractCustomer) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (phoneNumber == null) {
if (other.phoneNumber != null)
return false;
} else if (!phoneNumber.equals(other.phoneNumber))
return false;
return true;
}
#Override
public String toString() {
return "AbstractCustomer[name=" + name + ", phoneNumber=" + phoneNumber + "]";
}
}
And this is what I was trying to do:
public void createDataFile() {
try {
FileOutputStream fout = new FileOutputStream("C:\\Users\\Frank\\Desktop\\Assignment\\abstract.dat");
ObjectOutputStream outputStream = new ObjectOutputStream(fout);
outputStream.writeObject(HOW DO I WRITE THE ABSTRACT CLASS TO A FILE HERE????);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Any help is appreciated!
First of all, what you write using IO is an object, not a class. You can read in oracle documentation that:
Abstract classes cannot be instantiated, but they can be subclassed.
What you need to do, is either delete the abstract identifier (i don't see any abstract methods) or inherit this abstract class.
Only then will you be able to instantiate objects of the class (Not)AbstractCustomer and Serialize them using IO.
The only reason that your abstract class is Serializable, is for the classes that extend It, to be serializable as well. I hope this was clear enough.
Here's an example of serialization: (Note that i created a nested class that inherits the abstract class. Don't write It that way. I made it only for demonstration purposes. the main method won't work in that case):
// this cannot be serialized because no objects can be instantiated
public abstract class SerializationTest {
// this can be, because it's not abstract
public static class SerializationTestB extends SerializationTest {
public static void main(String[] args) {
// instantiation of an object that you want to write to file
SomeObject obj = new SomeObject(param, param, param);
SomeObject obj2 = new SomeObject(param, param, param);
SomeObject obj3 = new SomeObject(param, param, param);
SomeObject obj4 = new SomeObject(param, param, param);
SomeObject obj5 = new SomeObject(param, param, param);
SomeObject obj6 = new SomeObject(param, param, param);
// an object that represents the path of the file
File f = new File("some/path/here");
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
out.writeObject(obj);
out.writeObject(obj2);
out.writeObject(obj3);
out.writeObject(obj4);
out.writeObject(obj5);
out.writeObject(obj6);
out.flush();
out.close();
}
}
}
I'm trying to create a Manga app for Android where the each Chapter has its own Title,Publication Date, Description, etc. And each of said chapters belongs to a Manga object. Which would be a collection of Chapters and would include a list of the titles plus the Title of the Manga itself and the author('s) name(s). The data itself would be parsed from different webpages (but that's another mater).
My confusion is about the class declarations. (i.e. implements, extends)
Ive tried many things but as of right now my code consists of having chapters as an inner class like so:
public abstract class Manga implements MangaList {
public String name;
public String author;
public int chapters;
// names of the XML tags
static final String CHANNEL = "channel";
static final String PUB_DATE = "pubDate";
static final String DESCRIPTION = "description";
static final String LINK = "link";
static final String TITLE = "title";
static final String ITEM = "item";
private final URL feedUrl;
protected Manga(String feedUrl){
try {
this.feedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
protected InputStream getInputStream() {
try {
return feedUrl.openConnection().getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
List<Chapter> Chapter;
public class Chapter implements Comparable<Chapter> {
final SimpleDateFormat FORMATTER =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
private String title;
private URL link;
private String description;
private Date date;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title.trim();
}
// getters and setters omitted for brevity
public URL getLink() {
return link;
}
public void setLink(String link) {
try {
this.link = new URL(link);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description.trim();
}
public String getDate() {
return FORMATTER.format(this.date);
}
public void setDate(String date) {
// pad the date if necessary
while (!date.endsWith("00")){
date += "0";
}
date = "";
try {
this.date = FORMATTER.parse(date.trim());
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public Chapter copy(){
Chapter copy = new Chapter();
copy.title = title;
copy.link = link;
copy.description = description;
copy.date = date;
return copy;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Title: ");
sb.append(title);
sb.append('\n');
sb.append("Date: ");
sb.append(this.getDate());
sb.append('\n');
sb.append("Link: ");
sb.append(link);
sb.append('\n');
sb.append("Description: ");
sb.append(description);
return sb.toString();
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((date == null) ? 0 : date.hashCode());
result = prime * result
+ ((description == null) ? 0 : description.hashCode());
result = prime * result + ((link == null) ? 0 : link.hashCode());
result = prime * result + ((title == null) ? 0 : title.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;
Chapter other = (Chapter) obj;
if (date == null) {
if (other.date != null)
return false;
} else if (!date.equals(other.date))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (link == null) {
if (other.link != null)
return false;
} else if (!link.equals(other.link))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
public int compareTo(Chapter another) {
if (another == null) return 1;
// sort descending, most recent first
return another.date.compareTo(date);
}
}
My question is if this is an appropriate format or if there is a simpler way to create a List of Mangas, each with its own set of Chapters?
EDIT: I've looked it up and decided that using an SQLite Database would be a much simpler way to keep track of the large amount of data I will be parsing.
This way I can maintain two databases. One for Manga titles and authors, and another for the chapters and relevant information. The Related chapters will be linked to the Manga in each table through a reference ID.
I definitely think that there is an easier way to do this; however, it really depends on what you overall goal is. If you are trying to display this in a list you might consider using ListView, but if you are just using the data for content, then you can probably do something similar to what you have. Ultimately, you need to figure out what you are going to do with the app, then you can figure out the easiest way to implement it. Remember though: easier isn't always better. Try and think long term about your project as in who is going to be maintaining this, is it going to grow or shrink, and whether you will add features.
As for extends and implements they are subclasses and interfaces, respectively and has different rules regarding it and more information can be found here: http://docs.oracle.com/javase/tutorial/java/concepts/interface.html
Best of luck!