Вы можете попробовать следующий код. Он подсчитывает количество отдельных OrderNo для всех статусов. Надеюсь, это поможет.
val rawDF = Seq(
("123", "Completed", "Pending", "Pending"),
("456", "Rejected", "Completed", "Completed"),
("789", "Pending", "In Progress", "Completed")
).toDF("OrderNo", "Status1", "Status2", "Status3")
val newDF = rawDF.withColumn("All_Status", array($"Status1", $"Status2", $"Status3"))
.withColumn("Status", explode($"All_Status"))
.groupBy("Status").agg(size(collect_set($"OrderNo")).as("DistOrderCnt"))
Вот результаты. (Примечание: в прогрессе отображается только один раз в тестовых данных.)
+-----------+------------+
| Status|DistOrderCnt|
+-----------+------------+
| Completed| 3|
|In Progress| 1|
| Pending| 2|
| Rejected| 1|
+-----------+------------+
LinkedHashMap делает точно, что, см. javadoc для removeEldestEntry метода.
Что-то вроде этого должно добиться цели, это удалит самую старую вставленную запись:
Map map = new LinkedHashMap() {
@Override
protected boolean removeEldestEntry(Entry eldest) {
return size() > N;
}
};
Можно также удалить самую старую запись, к которой получают доступ, путем определения его в конструкторе:
Map map = new LinkedHashMap(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Entry eldest) {
return size() > N;
}
};
Вы ищете кэш LRU, возможно? Вот сообщение в блоге на одном на основе LinkedHashMap.
Можно хотеть рассмотреть использование Наборов Apache. У них есть набор реализаций LRU. Иначе можно легко записать подобную обертку для стандартных наборов библиотеки; я не думаю, что существует тот, который можно использовать непосредственно.
Вы могли использовать очередь с двусторонним доступом или Двухстороннюю очередь, и просто удалить первый объект, когда Вы в макс. количестве.
Если Вы кэшируетесь, Вы могли бы использовать WeakHashMap или WeakReference и затем не иметь для волнения о размере кэша.