' P '

whatever I will forget

AbstractMap.SimpleEntry

まだまだ全然知らないメソッドが沢山あって、奥深いなぁーと

最近使用したのは、AbstractMap.SimpleEntryです。
C++のように、make_pairをしたいときってどうするのかなぁと思っていたら、上記がでてきました。
javaFxにもPairというC++と同じようなClassがあるのですが、値の変更ができません
今回の要件はセットされたobjの値は変更したい、でも並び順はとりあえずQueueのFIFOになっていればよい、ということなので、下記のようにしました

つまづいたこと

  • genericの概念を完全に忘れてた。ちゃんと呼び出すときに<>つけてあげないとwarningでる
  • Queueを使いたい場合、大体はLinkedListPriorityQueueで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でいいや、と

参考

stackoverflow.com

  • 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();
    }
}