Object model
Each movie is represented as a Movie object with fields like title, year,
duration, rating, studio, summary, genres, directors, writers, and cast.
This was a Data Structures class project where I built a Java command-line movie database. The app loads movie records, stores them in memory, suggests random movies, searches by title, and lets the user add or remove movies from the running program.
The main point of the project was not just making a menu. It was choosing the right data
structures for the job: an ArrayList for storing and randomly selecting movies,
and a TreeMap for title lookup and prefix search.
I built a single-file Java console application called Movies.java. It defines a
movie record, loads data from a file when available, falls back to sample data when needed,
and gives the user an interactive menu.
Each movie is represented as a Movie object with fields like title, year,
duration, rating, studio, summary, genres, directors, writers, and cast.
The user can request a list of random movies, search by title, add a new movie, remove a movie, or quit from a simple terminal menu.
The project uses an ArrayList for movie storage and a TreeMap
for a searchable title index.
The app is small, but it has a complete working loop: load data, show a menu, process user input, update the movie list, and rebuild the title index when the data changes.
The user chooses how many movies to display, and the app prints that many distinct random movies.
The app normalizes titles, checks for exact matches first, then prints prefix matches.
The user can add a new movie through prompts, and the movie is appended to the list.
The user can remove the first movie with an exact matching title.
This was the core data structures part of the project. Each structure has a clear reason.
| Structure | Used for | Why it fits |
|---|---|---|
| ArrayList<Movie> | Main movie storage. | Good for appending records, iterating through movies, and selecting random movies by index in constant time. |
| boolean[] used | Tracking already-selected random movie indexes. | Prevents duplicates during a random suggestion run without modifying or shuffling the original movie list. |
| TreeMap<String, List<Movie>> | Title search index. | Stores normalized title keys in sorted order and maps each title key to one or more matching movie objects. |
| List<Movie> | Map value for duplicate title keys. | Allows more than one movie to share the same normalized title key. |
Random movie suggestions need fast indexed access. That makes ArrayList a good
choice because the program can generate a random index and immediately retrieve the movie at
that position.
ArrayList gives efficient indexed access, which is exactly what random
selection needs. The program generates a random index and uses it to pull a movie from
the list.
A LinkedList would be weaker here because indexed access requires walking
through the list. This project does not need frequent middle insertions or removals.
static void showRandom(ArrayList<Movie> list, int k) {
if (list.isEmpty()) {
System.out.println("(No Results)");
return;
}
int size = list.size();
int n = Math.min(k, size);
boolean[] used = new boolean[size];
int printed = 0;
while (printed < n) {
int idx = (int) (Math.random() * size);
if (used[idx]) continue;
used[idx] = true;
System.out.println("#" + (printed + 1) + ". " + list.get(idx));
printed++;
}
}
Search works better when titles are normalized. The program lowercases titles and removes
leading articles like the, a, and an.
static String normTitle(String s) {
if (s == null) return "";
s = s.trim().toLowerCase();
if (s.startsWith("the ")) return s.substring(4).trim();
if (s.startsWith("an ")) return s.substring(3).trim();
if (s.startsWith("a ")) return s.substring(2).trim();
return s;
}
The Matrix becomes matrix, so a user can
search for matrix without needing to type the leading article.
The title index maps a normalized title string to a list of matching movie objects. This is better than only storing titles because the program can retrieve and print the full movie record.
static Map<String, List<Movie>> buildTitleIndex(List<Movie> movies) {
Map<String, List<Movie>> index = new TreeMap<>();
for (Movie m : movies) {
String key = normTitle(m.title);
List<Movie> bucket = index.computeIfAbsent(key, k -> new ArrayList<>());
bucket.add(m);
}
return index;
}
HashMap would be faster for direct lookup on
average, but it does not keep keys sorted. TreeMap keeps keys ordered, which
makes it a better fit for prefix-style title search.
When the user searches, the program first checks for an exact normalized title match. After that, it scans the sorted keys for titles that start with the search text.
// Exact match first
List<Movie> exact = titleIndex.get(searchTitle);
if (exact != null) {
for (Movie m : exact) {
System.out.println(m);
}
}
// Prefix matches second
for (Map.Entry<String, List<Movie>> entry : titleIndex.entrySet()) {
String key = entry.getKey();
if (!key.startsWith(searchTitle) || key.equals(searchTitle)) continue;
for (Movie m : entry.getValue()) {
System.out.println(m);
}
}
contains().
The program tries to load a file named movies_data.tsv. It expects a header row
and exactly 12 tab-separated fields per movie.
| Column | Field | Example |
|---|---|---|
| 1 | id |
S001 |
| 2 | title |
The Matrix |
| 3 | year |
1999 |
| 4 | durationMinutes |
136 |
| 5 | criticRating |
8.7 |
| 6 | mpaaRating |
R |
| 7-12 | Studio, summary, genres, directors, writers, cast | Longer text fields from the movie dataset. |
String[] c = line.split("\t", -1);
if (c.length != EXPECTED_COLS) continue;
movies.add(new Movie(
c[0], c[1], c[2], c[3], c[4], c[5],
c[6], c[7], c[8], c[9], c[10], c[11]
));
If the TSV file is missing or no valid rows are loaded, the program falls back to a built-in sample dataset of 25 movies. That makes the project easier to demo because it still works without an external file.
ArrayList<Movie> movies = loadFile();
if (movies.isEmpty()) {
movies = seedSample();
System.out.println("File Not Found: Reverting to sample dataset");
} else {
System.out.println("Loaded " + movies.size() + " movies from: movies_data.tsv");
}
Adding and removing movies changes the main ArrayList. After either operation,
the program rebuilds the TreeMap title index so search results stay current.
The menu sends the program to the correct method.
A movie is appended, or the first exact title match is removed.
The title index is recreated from the updated movie list.
Future title searches reflect the current list.
case "3": {
addMovie(in, movies);
titleIndex = buildTitleIndex(movies);
returnToMenu(in);
break;
}
case "4": {
removeMovieByTitle(in, movies);
titleIndex = buildTitleIndex(movies);
returnToMenu(in);
break;
}
The project is small, but it still shows how data-structure choices affect performance.
| Operation | Approximate complexity | Reason |
|---|---|---|
| Append movie | Amortized O(1) |
ArrayList append is usually constant time. |
| Random indexed access | O(1) |
The app can directly access list.get(index). |
| Suggest K random movies | Expected about O(K) |
The app picks random indexes and uses a boolean array to avoid duplicates. |
| Exact title lookup | O(log n) |
TreeMap lookup is logarithmic. |
| Prefix search | O(n) |
This version scans the sorted map keys and checks startsWith(). |
| Remove by exact title | O(n) |
The program scans the list until it finds the first matching title. |
This project helped connect class data-structure concepts to a working program.
ArrayList is a good fit for indexed random access. TreeMap
is a better fit when sorted keys and prefix search matter.
The TSV loader has to preserve empty columns and skip malformed rows so the program does not build broken movie objects.
If the movie list changes, the search index has to be rebuilt or updated. Otherwise, search results can become stale.
The current version works for the assignment, but there are clear ways to make it more robust.
try/catch input validation for numbers.Movie class into its own file for larger versions.The project can be compiled and run directly with the Java compiler and runtime.
javac Movies.java
java Movies
movies_data.tsv in the same folder before
running. If the file is missing, the program falls back to sample data.
This project is a good example of a class assignment becoming a real portfolio piece. It shows Java basics, object modeling, file parsing, menu-driven programs, random access with ArrayList, associative lookup with TreeMap, and the reasoning behind choosing one data structure over another.