{"id":31831304,"url":"https://github.com/rbtr/boxerchallenge","last_synced_at":"2026-07-06T04:30:59.201Z","repository":{"id":32718861,"uuid":"36308601","full_name":"rbtr/BoxerChallenge","owner":"rbtr","description":"A relatively simple Android app that displays a list of emails. Written for an interview process.  ","archived":false,"fork":false,"pushed_at":"2015-05-26T18:09:56.000Z","size":1840,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-19T05:03:11.223Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rbtr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-26T16:22:40.000Z","updated_at":"2015-05-26T16:28:35.000Z","dependencies_parsed_at":"2022-09-13T08:10:23.722Z","dependency_job_id":null,"html_url":"https://github.com/rbtr/BoxerChallenge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rbtr/BoxerChallenge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rbtr%2FBoxerChallenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rbtr%2FBoxerChallenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rbtr%2FBoxerChallenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rbtr%2FBoxerChallenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rbtr","download_url":"https://codeload.github.com/rbtr/BoxerChallenge/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rbtr%2FBoxerChallenge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281366887,"owners_count":26488695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-27T02:00:05.855Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-11T21:49:11.098Z","updated_at":"2025-10-28T00:34:14.992Z","avatar_url":"https://github.com/rbtr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Boxer Challenge Notes  \nCreate an Android application that displays a list of email addresses and fulfills the requirements and specs listed below, and demonstrates your ability to code.\n\n\n## Requirements:  \n* Application that displays email addresses \n* Activity and ListFragment  \n* Has an Actionbar  \n* “ADD” menu item displays a DialogFragment with an EditText  \n* “Ok” DialogFragment button adds the email entry to the list  \n* The list should stay sorted with each addition  \n* Tapping an item should fire an email intent with the selected email as the “To:”  \n* Orientation changes don’t lose data  \n* Orientation changes don’t cause crashes  \n* Attempting to add an existing email address displays an AlertDialog  \n* AlertDialog informs the user the email already exists  \n* Duplicate emails are not added  \n* All Strings are localized, nothing hardcoded  \n* Empty emails are not added  \n* List persists throughout the Activity/Fragment lifecycle until they’re destroyed  \n* Leaving to home screen and reopening app should not lose data or list position  \n* Project well documented with comments and JavaDoc  \n* Project is thoroughly tested  \n* All Requirements/Specifications met  \n\n\n## Specifications:    \n* Email addresses displayed in ascending order  \n* Starts with fifteen (15) random email addresses in the list  \n* Supports any number of email addresses  \n* Has one (1) menu item – “ADD”  \n* DialogFragment EditText has hint of “Enter an e-mail address”  \n* DialogFragment has two (2) buttons – “Cancel” and “Ok”  \n* Email addresses should be horizontally centered  \n* Min SDK 14  \n* Target SDK 21  \n* Application Theme set to Theme.AppCompat.Light  \n\n\n# Problem solving discussion:  \n## Data Structures:  \nInitially, I wanted to use a TreeSet to hold all of the email String because it would self-sort. However, when I was building a custom Adapter to handle Sets I realized that because of the inability to index in to a Set, polling the email addresses to populate the ListView would become very inefficient the farther in to the List you got. (I’ve included that SetAdapter, which actually works alright, in misc/).  \nI migrated to using an ArrayList to be able to index and handled the sorting myself. To do that, I wrapped an ArrayList in a class called AlphabeticalArrayList. It overrides the #add() and #addAll() methods to insert a String in the correct alphabetical location up front, instead of sorting after the list is populated. To accomplish this, the #add*() methods defer to a #sortedAdd() method, which calls a binary search to determine where the passed String would be, if it existed in the List. I feel like this is good compromise on being able to sort, add data, and retrieve data efficiently.\n\n## Class Hierarchy:  \nBecause this is a relatively simple project, I left the hierarchy flat and didn’t try to coerce it into a MVC or other pattern. I did not design any parent classes; there is some inheritance of existing classes to modify their behavior.\nFragment callback Interfaces are defined as inner classes in their respective Fragments for organizational purposes.\nSome anonymous inner classes were utilized for onClick handling.\n\n## Persisting Data:  \nSince the amount of data I’m dealing with is relatively small, I made use of the savedInstanceState Bundle and methods (#putStringArrayList(), notably) to persist the list of emails through Activity recreations. Other options that I considered for this included a headless data Fragment (set to retainInstanceState) or writing out the List to an SQLite Database and reading it back in on-demand. \n\n## Documentation and Testing:  \nCode is verbosely commented with JavaDoc, block, and line comments. Some tests were written against the AlphabeticalArrayList class to verify its logic. Additionally, live testing was performed on two Android devices, a tablet and phone, running 5.1.1 and 4.4 respectively.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frbtr%2Fboxerchallenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frbtr%2Fboxerchallenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frbtr%2Fboxerchallenge/lists"}