まだまだ全然知らないメソッドが沢山あって、奥深いなぁーと
最近使用したのは、AbstractMap.SimpleEntry
です。
C++のように、make_pair
をしたいときってどうするのかなぁと思っていたら、上記がでてきました。
javaFx
にもPair
というC++と同じようなClassがあるのですが、値の変更ができません
今回の要件はセットされたobjの値は変更したい、でも並び順はとりあえずQueueのFIFOになっていればよい、ということなので、下記のようにしました
つまづいたこと
- genericの概念を完全に忘れてた。ちゃんと呼び出すときに
<>
つけてあげないとwarningでる - Queueを使いたい場合、大体は
LinkedList
かPriorityQueue
でnewするらしいが、AbstractMap
のobjをPriorityQueue
にaddしたら、下記エラー発生
Exception in thread "main" java.lang.ClassCastException: class Pair cannot be cast to class java.lang.Comparable (Pair is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
なんじゃこりゃ、と
理由は、PriorityQueue
自体が何を元に比較するのか内部でロジック(compareTo()
)があるけれども、単純に単数であれば内部ロジックで比較できるけど、連想配列のようにkeyとvalueのデータになってしまえば何を基準にしてpriorityをつけたらいいのか不明になってしまうため、ではないかと考えている。そのため、どうしてもPriorityQueue
を使用するのであれば、compareTo()
をoverrideしてあげないといけない。
まあ今回は単純にFIFOの並びで優越つけるほど厳密な要件ではないのでLinkedList
でいいや、と
参考
compareTo()
のオーバライド、勉強し直そう...peek()
は最初のobjを取得remove()
は最初のobjを削除
import java.util.Queue; import java.util.AbstractMap; import java.util.LinkedList; import java.util.Scanner; class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> { /** serialVersionUID. */ private static final long serialVersionUID = 1611421744L; public Pair(final K key, final V value) { super(key, value); } } public class QueueClassUsed { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int quantum = sc.nextInt(); Queue <Pair<String, Integer>> q = new LinkedList<Pair<String, Integer>>(); for(int i=0; i<n; i++) { q.add(new Pair<String, Integer>(sc.next(), sc.nextInt())); } int elapsedTime = 0; while(q.peek() != null) { Pair<String, Integer> currentQueue = q.peek(); int rst = Math.min(quantum, currentQueue.getValue()); int diff = currentQueue.getValue() - rst; elapsedTime += rst; q.remove(); if(diff > 0) { currentQueue.setValue(diff); q.add(currentQueue); } else { System.out.println(currentQueue.getKey() + " " + elapsedTime); } } sc.close(); } }