teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

全愛知を追加、クラス構成を変更

2020/11/26 06:33

投稿

xebme
xebme

スコア1109

answer CHANGED
@@ -1,3 +1,9 @@
1
+ **figure1/figure2の仮定**
2
+
3
+ figure2のインスタンスを用意しているので、figure1はシャッフルしないで元のまま残す、と仮定します。
4
+
5
+ ---
6
+
1
7
  **figure2**
2
8
 
3
9
  `figure2`のインスタンスをどうするか?`figure1`の要素を全て設定した後で複製するのが良いでしょう。
@@ -19,7 +25,7 @@
19
25
 
20
26
  **メソッド**
21
27
 
22
- 複製とシャッフル行うメソッドを書くとすれば次のようになります。
28
+ 複製とシャッフル行うメソッドを書くとすれば次のようになります。
23
29
 
24
30
  ```Java
25
31
  static Figure[] cloneShuffle(Figure[] figures) {
@@ -53,4 +59,85 @@
53
59
  }
54
60
  return result;
55
61
  }
56
- ```
62
+ ```
63
+
64
+ ---
65
+
66
+ **シャッフル別解**
67
+
68
+ 質問に対する[追記・修正依頼]で指摘した方法です。これは難しくなります。バグがあるかもしれません。
69
+
70
+ figure2の初期化。
71
+
72
+ ```Java
73
+ Figure [] figures2 = new Figure[figures1.length];
74
+ ```
75
+
76
+ シャッフル。
77
+
78
+ ```Java
79
+ Random rnd = ThreadLocalRandom.current();
80
+ for (int k = figures1.length; k > 0;) {
81
+ int index = rnd.nextInt(k);
82
+ temp = (figures2[index] == null) ? figures1[index] : figures2[index];
83
+ if (index != --k) {
84
+ figures2[index] = (figures2[k] == null) ? figures1[k] : figures2[k];
85
+ }
86
+ figures2[k] = temp;
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ **クラス名にインスタンス番号をつける**
93
+
94
+ カウンターをスレッドセーフにするために`java.util.concurrent.atomic.AtomicInteger`を使います。int型のcounterを使用すると`++counter`は2命令になりアトミックではないため。クラス構成にかなり問題がありましたので大幅に手直ししました。
95
+
96
+ ```Java
97
+ abstract class Figure {
98
+
99
+ final String name;
100
+
101
+ public Figure(String name) {
102
+ this.name = name;
103
+ }
104
+
105
+ abstract double getArea();
106
+
107
+ @Override
108
+ public String toString() {
109
+ return name + ":" + String.format("%.1f", getArea());
110
+ }
111
+
112
+ }
113
+ ```
114
+
115
+ Rectangleクラス
116
+
117
+ ```Java
118
+ class Rectangle extends Figure {
119
+
120
+ static final String NAME = Rectangle.class.getSimpleName();
121
+ static final java.util.concurrent.atomic.AtomicInteger counter = new AtomicInteger(0);
122
+ final int width;
123
+ final int height;
124
+
125
+ Rectangle() {
126
+ this(10, 20);
127
+ }
128
+
129
+ Rectangle(int width, int height) {
130
+ super(NAME + counter.addAndGet(1));
131
+ this.width = width;
132
+ this.height = height;
133
+ }
134
+
135
+ @Override
136
+ double getArea() {
137
+ return width * height;
138
+ }
139
+
140
+ }
141
+ ```
142
+
143
+ Circleも同様です。