[java] PriorityQueue는 어떻게 사용합니까?
PriorityQueue
정렬하려는 항목을 정렬하려면 어떻게해야 합니까?
답변
Comparator<? super E> comparator
정렬 순서에 적합한 방식으로 비교하는 비교자를 사용하여 생성자를 오버로드하십시오 . 정렬 방법에 대한 예제를 제공하는 경우 확실하지 않은 경우 비교기를 구현하는 샘플 코드를 제공 할 수 있습니다. (그러나 그것은 매우 간단합니다.)
로 다른 곳 말했다되었습니다 : offer
및 add
단지 다른 인터페이스 메소드 구현입니다. 내가 가진 JDK 소스에서을 add
호출하십시오 offer
. 비록 add
하고 offer
있을 가능성이 있는 능력으로 인해 다른 일반 동작 offer
값 인해 크기 제한에 추가 할 수없는 것을 나타 내기 위해서,이 차이에 무관 PriorityQueue
한 무제한이다.
다음은 우선 순위 대기열을 문자열 길이별로 정렬하는 예입니다.
// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;
public class Test {
public static void main(String[] args) {
Comparator<String> comparator = new StringLengthComparator();
PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator);
queue.add("short");
queue.add("very long indeed");
queue.add("medium");
while (queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
// StringLengthComparator.java
import java.util.Comparator;
public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String x, String y) {
// Assume neither string is null. Real code should
// probably be more robust
// You could also just return x.length() - y.length(),
// which would be more efficient.
if (x.length() < y.length()) {
return -1;
}
if (x.length() > y.length()) {
return 1;
}
return 0;
}
}
출력은 다음과 같습니다.
짧은
매질
참으로 길다
답변
자바 8 솔루션
Java 8에서 사용 lambda expression
하거나 method reference
도입 할 수 있습니다 . Priority Queue에 용량 값이 5 인 String 값이 저장되어있는 경우 인라인 비교기를 제공 할 수 있습니다 (String 길이 기준).
람다 식 사용
PriorityQueue<String> pq=
new PriorityQueue<String>(5,(a,b) -> a.length() - b.length());
메소드 참조 사용
PriorityQueue<String> pq=
new PriorityQueue<String>(5, Comparator.comparing(String::length));
그런 다음 그중 하나를 다음과 같이 사용할 수 있습니다.
public static void main(String[] args) {
PriorityQueue<String> pq=
new PriorityQueue<String>(5, (a,b) -> a.length() - b.length());
// or pq = new PriorityQueue<String>(5, Comparator.comparing(String::length));
pq.add("Apple");
pq.add("PineApple");
pq.add("Custard Apple");
while (pq.size() != 0)
{
System.out.println(pq.remove());
}
}
인쇄됩니다 :
Apple
PineApple
Custard Apple
순서를 반대로 바꾸려면 (최대 우선 순위 대기열로 변경) 단순히 인라인 비교기에서 순서를 변경하거나 다음 reversed
과 같이 사용하십시오 .
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Comparator.comparing(String::length).reversed());
우리는 또한 사용할 수 있습니다 Collections.reverseOrder
:
PriorityQueue<Integer> pqInt = new PriorityQueue<>(10, Collections.reverseOrder());
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Collections.reverseOrder(Comparator.comparing(String::length))
따라서 Collections.reverseOrder
사용자 정의 객체에 유용 할 수있는 비교기를 사용하기 위해 과부하되어 있음을 알 수 있습니다. reversed
실제로 사용 Collections.reverseOrder
:
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
offer () vs add ()
당으로 문서
offer 메소드는 가능하면 요소를 삽입하고 그렇지 않으면 false를 리턴합니다. 이것은 점검되지 않은 예외를 던져야 만 요소를 추가 할 수없는 Collection.add 메소드와 다릅니다. 오퍼 방법은 고정 용량 (또는 “바운드 된”) 큐에서와 같이 예외가 예외가 아닌 정상적인 경우에 사용하도록 설계되었습니다.
용량 제한 대기열을 사용하는 경우 일반적으로 offer ()가 add ()보다 선호되며, 예외를 던져야 만 요소를 삽입 할 수 없습니다. 그리고 PriorityQueue 인은 우선도 heap에 근거하는 무제한의 우선 순위 큐이다.
답변
생성자 에게 적절하게 전달 Comparator
하십시오 .
PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
유일한 차이점 offer
및 add
그들이 속한 인터페이스이다. 인터페이스에 원래 표시되는 반면,에 offer
속합니다 . 그 외에도 두 방법 모두 정확히 동일한 작업을 수행합니다. 지정된 요소를 우선 순위 대기열에 삽입하십시오.Queue<E>
add
Collection<E>
답변
에서 큐 API :
offer 메소드는 가능하면 요소를 삽입하고 그렇지 않으면 false를 리턴합니다. 이것은 점검되지 않은 예외를 던져야 만 요소를 추가 할 수없는 Collection.add 메소드와 다릅니다. 오퍼 방법은 고정 용량 (또는 “바운드 된”) 큐에서와 같이 예외가 예외가 아닌 정상적인 경우에 사용하도록 설계되었습니다.
답변
javadoc에서 선언 한 것과 다르지 않습니다.
public boolean add(E e) {
return offer(e);
}
답변
add()
대 offer()
질문 에 대답하기 만하면됩니다 (다른 질문은 완벽하게 답변을 받았으므로 그렇지 않을 수도 있음).
Queue 인터페이스의 JavaDoc에 따르면 , “제공 메소드는 가능한 경우 요소를 삽입하고 그렇지 않으면 false를 리턴합니다. 이는 Collection.add 메소드와 다르며, 점검되지 않은 예외를 던져서 만 요소를 추가 할 수 없습니다. offer 메소드는 다음을 위해 설계되었습니다. 예를 들어 고정 용량 (또는 “바운드 된”) 큐에서 예외가 아닌 실패가 정상적인 경우에 사용합니다. “
즉, 요소를 추가 할 수 있으면 (PriorityQueue에서 항상 그러해야 함) 요소는 정확히 동일하게 작동합니다. 그러나 요소를 추가 할 수 없으면 offer()
멋지고 예쁜 false
반환을 제공하면서 add()
코드에서 원하지 않는 불쾌한 예외를 throw합니다. 추가하지 못하면 코드가 의도 한대로 작동하거나 정상적으로 확인할 수있는 경우를 사용하십시오 offer()
. 추가에 실패한 것이 문제가 있는 경우 Collection 인터페이스의 사양add()
에 따라 발생하는 예외를 사용 하고 처리합니다 .
이 방법 offer()
은 false
( 용량 제한 큐에서 선호되는 메소드) 를 리턴하여 실패 를 지정하는 큐 인터페이스 에서 계약을 완료하고 예외를 발생시켜 항상 실패 를 지정add()
하는 콜렉션 인터페이스에서 계약을 유지 보수하는 방식으로 구현 됩니다 .
어쨌든, 그것은 질문의 적어도 그 부분을 분명히하기를 바랍니다.
답변
여기에서 사용자 정의 비교기를 정의 할 수 있습니다 :
아래 코드 :
import java.util.*;
import java.util.Collections;
import java.util.Comparator;
class Checker implements Comparator<String>
{
public int compare(String str1, String str2)
{
if (str1.length() < str2.length()) return -1;
else return 1;
}
}
class Main
{
public static void main(String args[])
{
PriorityQueue<String> queue=new PriorityQueue<String>(5, new Checker());
queue.add("india");
queue.add("bangladesh");
queue.add("pakistan");
while (queue.size() != 0)
{
System.out.printf("%s\n",queue.remove());
}
}
}
출력 :
india pakistan bangladesh
오퍼와 추가 메소드의 차이점 : 링크