イントロダクション
基本情報技術者試験の勉強を始めようと思いました。
試験問題の切り抜き を切り替えて問題を解く事ができます。※イメージファイルなので切り抜きになります。
このページを作成したのも、試験対策の一つです。
Javaで基本情報技術者の教科書を学ぶ
基数の単位
色々な記述がありましたが、パソコンは2進数 で様々な処理を行います。
2進数は、2になると1桁繰り上がります。表にすると下のようになります。
10進数
2進数
0
0
1
1
2
10
3
11
4
100
5
101
6
110
7
111
8
1000
9
1001
10
1010
データ量の単位
2進数の1桁を1ビットと呼ぶ「101」は3ビット
8ビット=1バイト(byte)
1000バイト(10の3乗)=1k(キロ)バイト
1000000バイト(10の6乗)=1M(メガ)バイト
表にすると下のようになります。
単位
10進数
2進数
k(キロ)
10の3乗
2の10乗
M(メガ)
10の6乗
2の20乗
G(ギガ)
10の9乗
2の30乗
T(テラ)
10の12乗
2の40乗
P(ペタ)
10の15乗
2の50乗
2進数の変換
上記で記載したように、パソコンは2進数を基本にしてデータを扱いますが、実際のところは10進数とか、8進数などの表示も行います。
そこで、2進数 ⇔ 10進数、2進数 ⇔ 16進数などのように、変換しています。これは、簡単な計算で行うことができます。
具体的には、下のように行います。
10進数からr進数への変換
xをrで割った時の商pとあまりqを求める
pが0ならば、計算終了、それ以外はpをxに置き換えて1を行う
計算した結果を下から順に並べなおす
10進数から2進数への変換
11を2進数に変換する場合
11を2で割る = 5 ... 1
5を2で割る = 2 ... 1
2を2で割る = 1 ... 0
1を2で割る = 0 ... 1
「計算した結果を下から順に並べなおす」 。この部分を間違えると計算が合わなくなります。つい上から順に見てしまいがちです。プログラマの習性でしょうか?
Javaプログラムの実行結果とコードを以下に示します。
public String toBinaryString(int num, int kisu) {
int p = num / kisu;
int q = num % kisu;
StringBuilder build = new StringBuilder();
while (p != 0) {
p = num / kisu;
q = num % kisu;
System.out.println("商: " + p + " 余り: " + q);
num = p;
build.append(q);
}
return build.toString();
}
小数点以下の変換
同様に、10進数から2進数への変換で、小数点以下のケースを行います。
x を r で乗算した結果を整数部の i と i を除いた小数値 d に分ける。
d の値が0ならば終了、そうでなければ1から繰り返す。
public String toBinaryString(Double num) {
int seisu = num.intValue();
StringBuilder build = new StringBuilder();
// 小数点第5位で切り捨て
Double r = nextDouble(num, 2);
build.append(r.intValue());
while (r != 1.0 && r != 0.0) {
r = nextDouble(r, 2);
System.out.println("次の小数: " + r);
build.append(r.intValue());
}
String bin = toBinaryString(String.valueOf(seisu));
return bin + "." + build.toString();
}
public Double nextDouble(Double num, int kisu) {
int i = num.intValue();
double d = new BigDecimal(num - i).setScale(5, RoundingMode.DOWN).doubleValue();
System.out.println("整数: " + i + " / 小数: " + d);
return d * kisu;
}
テストコード
@BeforeClass
public static void initBasicLogic() {
target = new BasicLogic();
}
@Test
public void testToBinary() {
System.out.println("*** 2進数への変換 ***");
System.out.println("0.625 => " + target.toBinaryString(0.625));
System.out.println("10.625 => " + target.toBinaryString(10.625));
// 循環小数なので変換不可能
//System.out.println("11.235 => " + target.toBinaryString(11.235));
}
r進数を10進数に変換
これは、2進数の「1」になっている部分を累乗で計算する。
2進数で「10」の場合
右からX番目
計算
計算結果の合計
1番目
0なので計算しない
0
2番目
2 の 1 乘
2
合計は 2 となり、2進数「10」を10進数に変換すると「2」になる。
2進数で「101」の場合
右からX番目
計算
計算結果の合計
1番目
2 の 0 乘
1
2番目
0なので計算しない
0
3番目
2 の 2 乘
4
合計は 5 となり、2進数「101」を10進数に変換すると「5」になる。
2進数で「1111」の場合
右からX番目
計算
計算結果の合計
1番目
2 の 0 乘
1
2番目
2 の 1 乘
2
3番目
2 の 2 乘
4
4番目
2 の 3 乘
8
合計は 15 となり、2進数「1111」を10進数に変換すると「15」になる。
数値表現
符号なしの値は使用しないので、無視します。
byte型8ビットのデータならば、ビットの数が8つ、つまり、最大値が以下のようになります。
//最大値は整数で127
byte maxByte = 1111111;
しかし、これを素直に計算すると、255になる。。。
これは、一番左のビット(2進数)の値を符号として見るためです。符号なしの場合は、255までの値になります。
C言語では「unsigned」修飾子で符号なしも使用できるようですが、Javaでは余り使用しませんので。。。こんなのもあるなぁ程度にしておきます。
2進数から r 進数に変換
これに関しては、2進数⇔10進数を除きます。
2進数から8進数
<例>
2進数の値を3つずつ区切り、3つの数を8進数に計算する。各値は下から並べる。
00101110
は10進数では「46」になります。※1byte=8bit
上の数値を下から、3つずつに区切ると下のようになります。
110 => 6
101 => 5
000 => 符号正の数を示すのと何もないので0で埋めて考えます。=一番左を0埋めする「000 101 110」
というわけで、「56」になります。
2進数から16進数
<例>
2進数の値を3つずつ区切り、4つの数を16進数に計算する。各値は下から並べる。
0101110
は10進数では「46」になります。
上の数値を3つずつに区切ると下のようになります。
0 => 符号正の数を示す
010 => 2
1110 = > 2E
というわけで、「2E」になります。
こちらのサイトでも確認しました。
他のケースは使用したことがないので、記載しません。。。
2進数の演算
そして計算は、なんのひねりもなく、そのまんま計算します。
参考サイトはこちら です。
<足し算>
<ひき算>
<かけ算>
<割算>
コンピュータが行う場合
上記の2進数演算ですが、人間がやる方法になります。
基本情報試験では、こちらの問題が出るようです。
こちらのサイトを参考 にしました。
補数を使った計算
補数とは。。。
「元の数」と「補数」を足した場合に桁上がりが発生する数のうち「最小」の数のことです。
そして、2進数では「1の補数」と「2の補数」があり、10進数にも、「10の補数」と、減基数の「9の補数」が存在します。8進数ならそれぞれ「8の補数」と「7の補数」です。
n進数の補数表現には、以下のものがあるということのようです。
n進数の補数表現には、それぞれ「nの補数」と「(nー1)の補数」が存在するのです。このnは「基数」であり、(n-1)は「減基数」です。
まとめると
n進数の補数表現 => 「nの補数」と「(nー1)の補数」がある
n = 「基数」
n - 1 = 「減基数」
具体的には
こちらのサイトも参考 にしました、
<10進数において>
「6」の補数は「4」 -> お互いに足したら桁が上がる最小の数
一方「9の補数」の場合、お互いに足しても桁が上がらない数の最大値は、10のべき乗から1を引いた値になります。
「6」の補数は「3」 -> 10の補数より1少ない数
わかりやすかった。
例えば、次のような計算をしたいとします。
"1195-171=1024"
ところがこの引き算という概念が使えない場合、足し算で同じ計算を行う方法があります。それに活用できるのが10の補数です。
→桁を繰り上げするために876を「補っている」という考え方。
<例>
10進数の123という数値で考えてみると、
123の9の補数は「876」 => 123を999にするために876を「補っている」という考え方。
123の10の補数は「987」 => 123を1000にするために876を「補っている」という考え方。
2進数で考えてみると、
1の補数と2の補数しか存在しませんね。2進数ですから。
0101の1の補数は「1010」。
各ビットを反転するだけでOK
では、「2の補数は?」
「0110」を例にすると
①ビットを反転 -> 「0110」を反転「1001」
②1を加算 -> 「1001」に1を加算「1010」
③確認をする
例のように4ビットで考えると、
最上位の1は無視されて加算結果が0になったかのように見えます。
これが補数を使った負の数の表現です。
補数表現を使うメリット
こちらのサイト を参考にしました。
「4 - 3」のケース
一方が負数であるような例として、4 + (-3)を考えよう。
00000100 ← 4
+ 11111101 ← -3 の2の補数表現
---------- ← 普通の足し算のつもりで足す
100000001 ← 9ビットになっている
↑あふれが出た。これを無視すると
00000001 となるが、これはもちろん 10進法の1である。
4 + (-3) = 1になる。
一般化して考えると。。。
x - y を計算したければ、
x + (y の全ビットを反転したもの) + 1
を求め、あふれが発生したら、それを無視すればよい、ということになる。
このように、2の補数表現では減算も容易にできる。回路設計の観点から 言えば、加算回路とビット反転回路を用意しておけば、減算ができるこ とになる。
練習
8ビットの2の補数表現で表された2つの数の間で以下のような演算を行 ないなさい:
(i) 01001010 - 00101101 を以下のようにして計算する。※計算の表示錠符号のビットが「0」のまま。。。
01001010 + (-00101101)(=10101101) を計算すればよい。※符号ビットが0は正数、1は負の数
まず、-00101101(=10101101) を求める。
01001010 の全ビットを反転すると、10110101 となる。
これに1を加えると 10110110 となる。これが 01001010 の2の補数表現。そこで、以下の筆算を行う。
01001010
+) 10110110
ーーーーーー
100000000 ←これは9ビットになっているので、下位8ビットだけをとると
答は 00000000
(ii) 上と同様にして、00110100 - 01001011 を計算しなさい。 今度はあふれが出るだろうか? 出ないだろうか? 予想してから計算してみなさい。
2進数の掛け算と割り算
2進数では2をかけるとケタが1つ左へずれ、 2で割ると1つ右へずれる
Javaで理解する
色々と調べてみたけれど、いまいち使用目的がはっきりしないままなので、そこを明らかにするべく、Javaで実装しながら、上の計算方法などを見直していきます。
そして、Javaでは常にビックエンディアン方式 で処理を行うようです。
そして、bit計算するにはjava.util.BitSet を使用するのが良いということがわかったのでそのようにします。がそれの使い方に関してJavaDocでわからなかったのでこちらのサイトを参考 にしました。
2進数から r 進数への変換処理(計算)
上で記載した方法(理論)で計算を行い、それが正しいのか検証します。
まずは、理論の確認から行きます。
r進数を10進数に変換
これは、2進数の「1」になっている部分を累乗で計算する。
まとめるのが大変だったけど以下のようにマトリまりました。
R進数の10進数に変換する式
X桁目の値 * RのX桁乘を合算する。
2進数で「10」の場合
「R = 2」
右からX番目
計算
計算結果の合計
0番目(X=0, 0桁目)
0なので計算しない
0
1番目(X=1, 1桁目)
2 の 1 乘
2
合計は 2 となり、2進数「10」を10進数に変換すると「2」になる。
2進数で「1010」の場合
右からX番目
計算
計算結果の合計
0番目(0桁目)
0なので計算しない
0
1番目(1桁目)
2 の 1 乘
2
2番目(2桁目)
0なので計算しない
0
3番目(3桁目)
2 の 3 乘
8
合計は 10 となり、2進数「1010」を10進数に変換すると「10」になる。
<コード>
public String convertBitToInt(BitSet set) {
BigDecimal ans = new BigDecimal(0);
for ( int i = 0; i < set.size(); i++) {
boolean bitValue = set.get(i);
if (bitValue) {
ans = ans.add(new BigDecimal(Math.pow(2, i -1)));
System.out.println(" / 計算後: " + ans.toString());
}
}
return ans.toString();
}
2進数で「101」の場合
右からX番目
計算
計算結果の合計
0番目
2 の 0 乘 * 1
1
1番目
0なので計算しない
0
2番目
2 の 2 乘 * 1
4
合計は 5 となり、2進数「101」を10進数に変換すると「5」になる。
<上のメソッドを実行したコード>
@Test
public void testToBinary_Theory1() {
// 2進数 10の場合
BitSet set = new BitSet(4);
set.set(2, true);
System.out.println("ANS1: " + target.convertBitToInt(set));
// 1010の場合
set.set(4, true);
System.out.println("ANS2: " + target.convertBitToInt(set));
// 101の場合
BitSet set2 = new BitSet(4);
set2.set(1, true);
set2.set(3, true);
System.out.println("ANS3: " + target.convertBitToInt(set2));
}
2進数で「111」の場合
右からX番目
計算
計算結果の合計
0番目
2 の 0 乘 * 1
1
1番目
2 の 1 乘 * 1
2
2番目
2 の 2 乘 * 1
4
合計は 7 となり、2進数「111」を10進数に変換すると「7」になる。
8進数で「101」の場合
右からX番目
計算
計算結果の合計
0番目
8 の 0 乘 * 1
1
1番目
0なので計算しない
0
2番目
8 の 2 乘 * 1
64
合計は 65 となり、8進数「101」を10進数に変換すると「65」になる。
16進数で「10F」の場合
右からX番目
計算
計算結果の合計
0番目
16 の 0 乘 * F (= 15)
15
1番目
0なので計算しない
0
2番目
16 の 2 乘 * 1
256
合計は 271 となり、16進数「101」を10進数に変換すると「271」になる。
<プログラムコード>
/**
* R進数を10進数に変換
* @param 変換元の数字
* @param 〜進数に変換するか
* @return 10進数の数字 / エラーの場合はNULLを返却
*/
public String convertRsinsuToInt(String numeric, int r) {
System.out.println("*** 計算開始 ***");
// 文字列でR進数を受け取る
if (numeric == null && r != 0 && !numeric.matches("[0-9a-fA-F")) {
return null;
}
char[] chList = numeric.toCharArray();
// 計算結果
int answer = 0;
for (int i = 0; i < chList.length; i++) {
String st = String.valueOf(chList[chList.length - (i + 1)]);
int value = 0;
int stVal;
if (st.matches("[0-9]")) {
stVal = Integer.parseInt(st);
} else {
stVal = Integer.parseInt(st, 16);
}
value = stVal * (int) Math.pow(r, i);
System.out.println(i + "桁目"+ " / 値: " + value);
answer += value;
}
return String.valueOf(answer);
}
<テストコード>
@Test
public void testRsinsuToInt() {
System.out.println("2進数で101 = " + target.convertRsinsuToInt("101", 2));
System.out.println("8進数で101 = " + target.convertRsinsuToInt("101", 8));
System.out.println("16進数で101 = " + target.convertRsinsuToInt("10F", 16));
}
補数を使った減算
パソコンでの減算処理は、内部的に補数を使用していて、「32 - 4」は「32 + (-4)」で計算されるようです。
※パソコンは減算ができないらしいです。
参考サイトはこちら です。
まずは、ビット演算の確認
下のように作成したコードを実行しました。
<プログラムコード>
@Test
public void testHosu() {
int value1 = 0b0100;//[1]=4
int value2 = 0b0010;//[2]=2
System.out.println("value1 = " + Integer.toBinaryString(value1));
System.out.println("value2 = " + Integer.toBinaryString(value2));
// AND演算
System.out.println("value1 & value2 = " + (value1 & value2));
// OR演算
System.out.println("value1 | value2 = " + (value1 | value2));
// XOR演算
System.out.println("value1 ^ value2 = " + (value1 ^ value2));
// ビットを反転(1byte(=8bit)で計算)
Byte b = 0b1010101;
System.out.println("~b = " + ( b + (~b)));
Byte b1 = 0b0001;
System.out.println("~b1 = " + ( b1 + (~b1)));
Byte b2 = 0b0101;
System.out.println("~b2 = " + ( b2 + (~b2)));
Byte b3 = 0b0110;
System.out.println("~b3 = " + ( b3 + (~b3)));
}
ここからわかることは、「補数 = ~x」 ではないといことです。
調べて見ると、上のような記載のあるサイトが多少見受けられたが、どうやら違うようです。※自分の解釈が違った可能性もありますが。。。
こちらのサイト にあるように、
ビット単位の補数演算子(bitwise complement operator)
オペランドに対して単項数値昇格変換を行った結果の全ビットを反転した値を得るための単項演算子。~xは(-x) - 1と等しい。
オペランドの型は、整数型に変換可能な型でなければならない。
早い話が「~X = X + 1 = 0」になるということです。=> 別の言い方をすると右の計算結果は必ず「-1」になる「X + (-X)」といことです。
「~」演算子の処理内容
ビット反転処理を行う演算子でした。
つまり、「補数」というのは、R進数における、ある値Xのビットを反転し、1を加算した値となります。
<式で表現する>
「~X = -(X + 1)」
「X + (-X) = -1」
そして、補数の考え方を合わせると下のようになり。。。
X - X = X + (~X + 1) = 0
10進数における、6の補数は4
というのは、「10 = 6 + 4」になり、一般化(文字に置き換え)すると下のようになります。
R進数における、Xの補数はY
=> 「R = X + (~X + 1)」
<プログラムコード>
int hosu = 6;
System.out.println(hosu + " => 2進数表現: " + Integer.toBinaryString(hosu) + " / 10進数=" + hosu);
System.out.println(hosu + " => ビット反転: " + Integer.toBinaryString(~hosu) + " / 10進数=" + ~hosu);
System.out.println("10進数、6の補数は4: " + (10 + (~hosu + 1)));
これを一般化して、メソッドにすると下のようなコードになります。ついでなので実装風景を動画にしてみました。テストファーストで実装しました。
<動画>
<プログラムコード>
@Test
public void testHosu2() {
// 前提として、10進数(int型)で実装する
// テストケースとして、ビット反転した時に、値が「~X = -(X + 1)」になることを確認する。
// 2進数表現での6
int num = 0b0110;
assertEquals(-7, ~num);
// R進数における、ある値Xの補数を算出する
// 10進数における、6の補数は4
assertEquals("4", target.convertHosu(6)); // これからメソッドの実装をする
}
VIDEO
R進数におけるXの補数Y
今までに記載してきたことをまとめて、プログラムにすると下のようになりました。
/**
* 上のメソッドのオーバーロード。
* R進数における、引数の値を補数に変換する。
*
* @param num 元になる数値
* @param sinsu ?進数
* @return numの補数(文字列) / 想定外の入力はNULLを返す
*/
public String convertHosu(byte num, int sinsu) {
// 10進数における、補数の算出, int型が10進数なので想定と違う
// ステップ1:取得した値を文字列に変換
String bStr = null;
if (sinsu == 8) {
bStr = Integer.toOctalString(num);
} else if (sinsu == 2) {
bStr = Integer.toBinaryString(num);
} else {
return null;
}
System.out.println(sinsu + "進数: " + bStr);
char[] ch = bStr.toCharArray();
int ans = 0;
int keta = ch.length;
for (int i = 0; i < ch.length; i++) {
String st = String.valueOf(ch[i]);
Double bit = Double.parseDouble(st);
// Rの(i - 1)桁目の値で累乗
System.out.print("値: " + bit + " / 桁: " + ((keta - 1)- i));
Double val = bit * Math.pow(sinsu, ((keta - 1) - i));
System.out.println(" => 計算後: " + val);
ans += val;
}
System.out.println("合計: " + ans);
//int hosu = sinsu + (~num + 1);
return String.valueOf(ans);
}
しかし、この場合は引数が16進数だった場合には、桁数が溢れてしまう(2進数表現で1バイトに収まらない)ため、メソッドのオーバーロードを行いました。
/**
* 16進数は、1バイトで治らないのでshortにする。
*
* @param num 元になる数値
* @param sinsu ?進数
* @return numの補数(文字列) / 想定外の入力はNULLを返す
*/
public String convertHosu(short num, int sinsu) {
// ステップ1:取得した値を文字列に変換
String bStr = null;
if (sinsu == 16) {
bStr = Integer.toHexString(num);
} else if (sinsu == 8) {
bStr = Integer.toOctalString(num);
} else if (sinsu == 2) {
bStr = Integer.toBinaryString(num);
} else {
return null;
}
System.out.println(sinsu + "進数: " + bStr);
char[] ch = bStr.toCharArray();
int ans = 0;
int keta = ch.length;
String st = String.valueOf(ch[i]);
Double bit = null;
if (st.matches("[0-9]")) {
bit = Double.parseDouble(st);
} else if (st.matches("[a-fA-F]")) {
bit = (double) Integer.parseInt(st, 16);
}
// Rの(i - 1)桁目の値で累乗
System.out.print("値: " + bit + " / 桁: " + ((keta - 1)- i));
Double val = bit * Math.pow(sinsu, ((keta - 1) - i));
System.out.println(" => 計算後: " + val);
ans += val;
System.out.println("合計: " + ans);
//int hosu = sinsu + (~num + 1);
return String.valueOf(ans);
}
<テストコード>
@Test
public void testHosu4_Convert1() {
// R進数におけるXの補数Y
// 8進数「113」の補数を算出する
byte b8 = 0113;
assertEquals("75", target.convertHosu(b8, 8));
short b16 = 0x113;
assertEquals("275", target.convertHosu(b16, 16));
}
ようやくカタが着きました。2進数から?進数に変換する理論がわかったと思います。
今回はこんなところで。。。
でわでわ。。。
関連ページ一覧
Eclipse セットアップ
Java Install Eclipse 〜開発ツールのインストール〜
TensorFlow C++ 環境〜 Eclipse に CDT をインストール〜
Setup OpenGL with Java 〜 JOGL を使う準備 for Eclipse 〜
Eclipse Meven 開発手順〜プロジェクトの作成〜
Java OpenCV 環境セットアップ (on Mac)
Eclipse SceneBuilder を追加する
JavaFX SceneBuilder 〜 Eclipse と SceneBuilder 連携 ~
Java Basic一覧
Java Basic Level 1 〜Hello Java〜
Java Basic Level2 〜Arithmetic Calculate〜
Java Basic Level3 〜About String class〜
Java Basic Level 4〜Boolean〜
Java Basic Level 5〜If Statement〜
Java Basic Summary from Level1 to 5
Java Basic Level 6 〜Traning of If statement〜
Java Basic Level8 〜How to use for statement〜
Java Basic Level 8.5 〜Array〜
Java Basic Level 9〜Training of for statement〜
Java Basic Level 10 〜While statement 〜
Java Basic Swing〜オブジェクト指向〜
Java Basic Swing Level 2〜オブジェクト指向2〜
サンプル実装〜コンソールゲーム〜
Java Basic インターフェース・抽象クラスの作り方
Java Basic クラスとは〜Step2_1〜
Java Basic JUnit 〜テストスイートの作り方〜
Git関連
Java Git clone in Eclipse 〜サンプルの取得〜
Eclipse Git リポジトリの取得 〜 Git からソースを Pull しよう〜
IntelliJ IDEA Git 〜 Git リポジトリからクローン〜
JavaFX関連ページ
Eclipse SceneBuilderを追加する
JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜
ステップアップ関連ページ一覧
Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
ステップアッププログラミング〜Java FxでHelloWorld解説〜
Java StepUpPrograming〜JavaFX で四則計算〜
Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine
JavaFX + ND4Jで機械学習準備
JavaFX + ND4J〜数学への挑戦1:ND4Jのインストール〜
JavaFX + ND4J〜数学への挑戦2: 行列の計算〜
Java + ND4J 〜数学への挑戦3: ベクトル(配列)の作成方法〜
オブジェクト指向関連ページ
[オブジェクト指向の概念1〜OracleDocのチュートリアル1〜](https://zenryokuservice.com/wp/2019/10/301 . /%e3%82%aa%e3%83%96%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e6%8c%87%e5%90%91%e3%81%ae%e6%a6%82%e5%bf%b5-%e3%80%9coracledoc%e3%81%ae%e3%83%81%e3%83%a5%e3%83%bc%e3%83%88%e3%83%aa%e3%82%a2%e3%83%ab%ef%bc%91/)
オブジェクト指向の概念2〜クラスとは〜
Java Discord
IntelliJ IDEA Discord Botを作る〜Gradle環境のセットアップ〜
Java Discord セットアップ〜Hello Discord〜
Java Discord ピンポン〜Discordプログラム〜
Java Discord Listener実装〜コマンドを好きなだけ追加しよう〜