質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

Q&A

1回答

383閲覧

片方向リストの作り方

coala

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

0グッド

1クリップ

投稿2021/06/02 08:53

ゲッターとセッターを用いちて片方向リストを作成しているのですが、headが次のデータを取得しません。
Gameクラスでゲッターとセッターを作成し、GameListクラスでゲッターセッターを使用して片方向リストを用いてGameをaddメソッド(GameList内の)を使用して追加したいと考えています。
私のGameListクラスでは、なぜ片方向リストが作成されないのでしょうか。
Headをcurrentとしてループで回してheadを移動させているつもりなのですが、、、
ご教示いただけないでしょうか。
よろしくお願い致します。

public class Game { private String name; private Calendar released; private Game next;//private -> public private int totalTrophies; public Game(String name, Calendar released, int totalTrophies) {// empty -> parameter (Game next+others) this.next = null; this.name = name; this.released = released; this.totalTrophies = totalTrophies; } public Game(String name, Calendar released, int totalTrophies, Game next) { try { this.next = next; this.name = name; this.released = released; this.totalTrophies = totalTrophies; } catch (Exception e) { System.out.println("Something went wrong."); } } public String toString() { // create date format SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy"); // "Assassin's Creed IV: Black Flag", released on: Nov 29, 2013 String str = "\"" + name + "\"" + ", released on: " + dateFormat.format(released.getTime()); return str; } @Override public boolean equals(Object o) { if(o == null) { return false; } if(o.getClass() != this.getClass()) { return false; } if(!this.name.equals(((Game)o).name)){ return false; } if(this.released != ((Game)o).released) { return false; } if(this.totalTrophies != ((Game)o).totalTrophies) { return false; } return true; } public Calendar getReleased() {//Object -> Calendar return released; } public int getTotalTrophies() {//Object -> int return totalTrophies; } public String getName() {//Object -> String return name; } public void setNext(Game g2) { this.next = g2; } public Game getNext() { return next; } }
public class GameList { public Game head; // public GameList() {//I made // // } public GameList(Game head) { this.head = head; } public void addGame(Game game) throws IllegalArgumentException{ if(game == null) { throw new IllegalArgumentException("The object of game is null."); } Game newGame = new Game(game.getName(),game.getReleased(),game.getTotalTrophies()); Game current = head; // // Initialise Game only incase of 1st element if(head == null) { head = newGame; System.out.println("head: "+ head); } else { // starting at the head, crawl to the end of the list and then add element after last node while(current.getNext() != null) { current = current.getNext(); } // the last node's "next" referene set to our new node current.setNext(newGame); System.out.println("current: "+current); } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2021/06/02 09:17

実際にリストを作成するmainメソッドなどを提示してください。
guest

回答1

0

片方向リストを作成、とありますが、LinkedList ではできないことをしたいということでしょうか。
質問文とソースコードを拝見した限り、GoF の Chain of Responsibility のようなことを
将来的に実現したいためのクラスを作りたいということでしょうか。

少し疑問は残りつつ、
ソースコードでは、「配列の末尾の要素に、要素を追加する」というのが目的であれば、
正常に要素を追加できているように見えます。
記号をつかって関係性を表すと以下の状態です。

Game には、 gameA, gameB, gameC, gameD があるとする。 連鎖の状態は以下となっているとする。 - gameA -> gameB -> null - gameC -> gameD -> null GameList の head に gameA が入った状態で、gameC を追加する。 その時の連鎖の状態は以下 - gameA(head) -> gameB -> gameC -> gameD -> null

ただ、「head を移動させて」という表現が気になっており、
もしかして今回の実現したい目的というのは
「配列の先頭の要素を追加し、追加した要素の最後に以前先頭(head)だったものを追加したい」ということでしょうか?

Game には、 gameA, gameB, gameC, gameD があるとする。 連鎖の状態は以下となっているとする。 - gameA -> gameB -> null - gameC -> gameD -> null GameList の head に gameA が入った状態で、gameC を追加する。 その時の連鎖の状態は以下 - gameC(head) -> gameD -> gameA(最初のhead) -> gameB -> null

であれば、以下のように処理を実装する必要があると思われます

  • GameList.addGame() に渡された game の末尾の要素をさがしだす
  • とりだした末尾の game 要素に、GameList.head を追加する
  • GameList.head を、渡された game で更新する(新しい連鎖の先頭要素)

具体的な実装としては以下

Java

1 static class GameList { 2 3 private Game head; 4 5 6 public GameList(Game head) { 7 this.head = head; 8 } 9 10 public void addGame(Game game) throws IllegalArgumentException{ 11 if(Objects.isNull(game)) { 12 throw new IllegalArgumentException("The object of game is null."); 13 } 14 15 // head の更新 16 head = Optional.ofNullable(head) 17 .map(h -> { 18 Game tail = getTail(game); 19 /* 20 * getTail() の部分は以下と同じです. 21 * Game current = game; 22 * while(!Objects.isNull(current.getNext())) { 23 * current = current.getNext(); 24 * } 25 */ 26 tail.setNext(head); // 受け取った Game の末尾に head を追加 27 System.out.printf("debug: tail is [%s]\n", tail); // debug 用. 追加した Game の情報. 28 return game; // GameList の先頭を更新 29 }).orElse(game); 30 31 System.out.printf("debug: head is [%s]\n", head); // debug 用 32 } 33 34 private Game getTail(Game game) { 35 // game 自体は null ではないものとする 36 if (Objects.isNull(game.getNext())) { 37 // next がなかったら渡された game が最後の要素 38 return game; 39 } else { 40 // next があれば、次の game を取りに行く 41 return getTail(game.getNext()); 42 } 43 } 44 45 /** 46 * debug 用. 47 * 配列の要素に追加した Game の情報を末尾まで標準出力する 48 */ 49 public void printDebugGameChains() { 50 System.out.printf("=== head: [%s]\n", head); 51 var current = head; 52 while(!Objects.isNull(current.getNext())) { 53 var next = current.getNext(); 54 System.out.printf("=== next: [%s]\n", next); 55 current = next; 56 } 57 } 58

実際に main を以下のようにすると、C->D->A->B の順番になっているかと思います。

public static void main(String[] args) { final var gameA = new Game("gameA", Calendar.getInstance(), 1); final var gameB = new Game("gameB", Calendar.getInstance(), 1); gameA.setNext(gameB); final var list = new GameList(gameA); final var gameC = new Game("gameC", Calendar.getInstance(), 2); final var gameD = new Game("gameD", Calendar.getInstance(), 2); gameC.setNext(gameD); list.addGame(gameC); list.printDebugGameChains(); }

実行結果

debug: tail is ["gameD", released on: 6月 05, 2021] debug: head is ["gameC", released on: 6月 05, 2021] === head: ["gameC", released on: 6月 05, 2021] === next: ["gameD", released on: 6月 05, 2021] === next: ["gameA", released on: 6月 05, 2021] === next: ["gameB", released on: 6月 05, 2021]

投稿2021/06/05 13:39

編集2021/06/05 13:41
kiino

総合スコア539

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問