1999年 - 2002年の間ネブラスカ大学に在籍。コーンハスカーズのエースピッチャーとして活躍する。後に同僚となるダン・ジョンソンはネブラスカ大時代のチームメイト。2002年、オークランド・アスレチックスからドラフト9巡目で指名される。ミッドランド・ロックハウンズ（AA）、サクラメント・リバーキャッツ（AAA）と昇格し、2006年7月26日にメジャー昇格。2006年7月30日のブルージェイズ戦でメジャーデビュー、6イニングを投げて自責点1（奪三振1、四球4）に抑えている。2007年7月17日、レンジャーズ戦に8回から登板した際、同じハワイ出身で日系人のカート・スズキとバッテリーを組んだ。これは、ハワイ出身者同士のバッテリーとしてメジャーリーグ史上初であった。
ロンドン出身ながら、代表はユース世代から一貫してウェールズ代表でプレー。2017年のトゥーロン国際大会に、U-21代表で出場。翌2018年3月には、クリス・コールマン前監督から引き継いだライアン・ギグス新代表監督の初陣となった中国杯に、フル代表に初招集された。
10歳の時に地元のチェルシーFCのアカデミーチームに入団するも、14歳の時に放出され、その後ワトフォードFCやQPRの入団も断られた後、2012年にブレントフォードFCのアカデミーチームに入団。ユースチームで力を付け、2016年2月にプロ契約を締結。リザーブチームに登録された。2016-17シーズンにトップチームに昇格し、2017年1月6日に 2年間の契約延長に合意。翌日のFAカップ3回戦のイーストリーFC戦で、トップチームデビューを果たし、5-1で勝利。同シーズンのリザーブチームの最優秀選手に選出された。更に2017-18シーズン中には5年間の契約延長を締結するなど、チームの中心選手に成長した。2019年1月22日、AFCボーンマスに移籍した。
1998年、ドラフト5位でレッドソックスに入団。2002年にメジャー初昇格。2003年、フィラデルフィア・フィリーズに移籍。翌2004年、シンシナティ・レッズに移籍。2006年にセントルイス・カージナルスに移籍し、自身初の世界一を経験。この年は、中継ぎとして62試合に登板した。2007年4月29日深夜、交通事故により29歳で死去。事故から数日後、ジョシュが飲酒運転であったこと、また車の中からマリファナが発見されたことがセントルイス警察より発表された。最後の登板は事故前日のシカゴ・カブス戦で、中継ぎとして3回1失点の成績であった。
素集合森 (disjoint-set forest) はそれぞれの集合を木構造で表したデータ構造で、各ノードには親ノードへの参照がある。1964年、Bernard A. Galler と Michael J. Fischer が考案したが、詳細な解析にはその後何年かかかった。素集合森では、各集合の代表は木構造の根となる。Findは親ノードへのリンクを根に到達するまでたどっていく。Unionは2つの木構造を1つにする操作であり、どちらかの根が全体の根となる。以下に素集合森の実装例を擬似コードで示す。 function MakeSet(x)     x.parent := x  function Find(x)     if x.parent == x        return x     else           return Find(x.parent)  function Union(x, y)     xRoot := Find(x)     yRoot := Find(y)     xRoot.parent := yRootこの素朴な実装では、連結リストを使った場合と変わらない。なぜなら、木構造の平衡が保たれないからである。しかし、これを改善する方法が2つある。第一の方法は union by rank と呼ばれ、Union操作で常に大きい木の方が全体の根になるように連結するものである。木の大きさを評価するにはrank を用いる。これは、1要素の木の rank を 0 とし、同じ rank r の木を連結したとき、全体の根とした方の木の rank を r+1 とするものである。このようにするだけで、MakeSet、Union、Find 操作の償却実行時間は  となる。改良した MakeSet と Union の擬似コードは以下のようになる。 function MakeSet(x)     x.parent := x     x.rank   := 0  function Union(x, y)     xRoot := Find(x)     yRoot := Find(y)     if xRoot.rank > yRoot.rank         yRoot.parent := xRoot     else if xRoot.rank < yRoot.rank         xRoot.parent := yRoot     else if xRoot != yRoot // x と y が同じ集合にない場合だけマージする。         yRoot.parent := xRoot         xRoot.rank := xRoot.rank + 1第二の改善は path compression と呼ばれ、Find操作を行ったときに構造を平坦化するものである。Findで根ノードまでのリンクをたどっているとき、各ノードは同じ代表を共有しているので、それらを根ノードに直接接続できる。このため、Find は再帰的にたどったノードが全て親ノードとして根ノードを指すように変更する。こうすると木構造はより平坦になり、その後の操作が高速化される。以下に Find の改良版を示す。 function Find(x)     if x.parent == x        return x     else        x.parent := Find(x.parent)        return x.parentこれらの手法は相補的であり、これを共に行うことで各操作の償却実行時間は  となる。ここで  は関数  の逆であり、 は非常に高速に大きな値になるアッカーマン関数である。 はその逆関数なので、実用的な  の値に対しては常に 5 未満の値になる。したがって、各操作の償却実行時間は事実上非常に小さな定数となる。実際、これは漸近最良である。Fredman と Saks は1989年、どのような素集合データ構造でも1回の操作あたり平均で  のノードにアクセスするとした。