Предлагаю вам попробовать следующий пример. Если вы используете PriorityQueue в качестве очереди, записи удаляются в порядке.
import java.util.Comparator;
import java.util.PriorityQueue;
public class Main {
public static void main(String... args) {
PriorityQueue<Flight> flights = new PriorityQueue<Flight>(5, new SortQueueViaPriority());
flights.add(new Flight("0001", 9));
flights.add(new Flight("0002", 7));
flights.add(new Flight("0003", 1));
flights.add(new Flight("0004", 2));
flights.add(new Flight("0005", 1));
while (!flights.isEmpty())
System.out.println(flights.remove());
}
}
class SortQueueViaPriority implements Comparator<Flight> {
@Override
public int compare(Flight f1, Flight f2) {
return Integer.compare(f2.getPriority(), f1.getPriority());
}
}
class Flight {
private final String name;
private final int priority;
Flight(String name, int priority) {
this.name = name;
this.priority = priority;
}
public int getPriority() {
return priority;
}
@Override
public String toString() {
return "Flight{" +
"name='" + name + '\'' +
", priority=" + priority +
'}';
}
}
печатает
Flight{name='0001', priority=9}
Flight{name='0002', priority=7}
Flight{name='0004', priority=2}
Flight{name='0003', priority=1}
Flight{name='0005', priority=1}
Примечание: PriorityQueue сортирует записи таким образом, что только первый элемент будет маленький. Если вы перейдете по очереди, вы увидите все элементы, но они могут быть или не быть в порядке.
Да, вы можете перегрузить invoke
. Вот пример:
class Greeter(val greeting: String) {
operator fun invoke(target: String) = println("$greeting $target!")
}
val hello = Greeter("Hello")
hello("world") // Prints "Hello world!"
В дополнение к тому, что сказал @ holi-java, переопределение invoke
полезно для любого класса, где есть четкое действие, необязательно взятие параметров. Это также отлично, как функция расширения классов библиотеки Java с таким методом.
Например, скажем, что у вас есть следующий класс Java
public class ThingParser {
public Thing parse(File file) {
// Parse the file
}
}
. В Kotlin вы можете определите расширение ThingParser следующим образом:
operator fun ThingParser.invoke(file: File) = parse(file)
И используйте его так:
val parser = ThingParser()
val file = File("path/to/file")
val thing = parser(file) // Calls Parser.invoke extension function
Наиболее удобный способ использования invoke использует его как Factory Method , например:
// v--- call the invoke(String) operator
val data1 = Data("1")
// v--- call the invoke() operator
val default = Data()
// v-- call the constructor
val data2 = Data(2)
Это происходит потому, что объект-компаньон является специальным объектом в Котлине. В самом деле, код Data("1")
выше переводится в код, как показано ниже:
val factory:Data.Companion = Data
// v-- the invoke operator is used here
val data1:Data = factory.invoke("1")
class Data(val value: Int) {
companion object {
const val DEFAULT =-1
// v--- factory method
operator fun invoke(value: String): Data = Data(value.toInt())
// v--- overloading invoke operator
operator fun invoke(): Data = Data(DEFAULT)
}
}
Data
в интерфейс, вы поймете, почему?
– holi-java
31 July 2017 в 11:21
ThingParser
просто анализирует файл и преобразует его содержимое вThing
. То, что это или как это работает, не имеет значения, просто что у него есть функцияparse(File)
, которая является явным основным действием класса. – Ruckus T-Boom 18 July 2017 в 19:41