Cómo encontrar la última fecha del valor del mapa dado en Java
date lambda (6)
Tengo un mapa hash con los valores a continuación, en valores que he fechado como tipo de datos de cadena. Me gustaría comparar todas las fechas disponibles en el mapa y extraer solo un valor-clave que tenga una fecha muy reciente.
Me gustaría comparar con valores, no con claves.
He incluido el código a continuación
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("1", "1999-01-01");
map.put("2", "2013-10-11");
map.put("3", "2011-02-20");
map.put("4", "2014-09-09");
map.forEach((k, v) -> System.out.println("Key : " + k + " Value : " + v));
}
}
El resultado esperado para este es:
Valor clave 4 09/09/2014
A primera vista, usar literales de cadena para representar Date no es un buen enfoque y lo hace más frágil y propenso a errores.
Preferiría usar
LocalDate
en primer lugar.
Sin embargo, con el supuesto de que no tiene ningún control sobre ese formato de datos (por ejemplo, proviene de otro sistema de terceros), aún podemos idear un enfoque que resuelva el problema en cuestión.
Así es como se ve.
Entry<String, String> maxEntry = map.entrySet().stream()
.max(Comparator.comparing(e -> LocalDate.parse(e.getValue())))
.orElseThrow(IllegalArgumentException::new);
LocalDate.parse
se utiliza para convertir la representación de cadena de la fecha en un
LocalDate
que es comparable.
Ese
Comparable
se pasa como una clave para el método de construcción del
Comparator
.
Y aquí está el par clave-valor de salida después de la ejecución exitosa:
4=2014-09-09
Si simplemente puede prescindir de la representación de fecha de String como se sugirió anteriormente, puede hacer que la solución anterior sea mucho más simple y sucinta.
Entry<String, LocalDate> maxEntry = map.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElseThrow(IllegalArgumentException::new);
Esto debería funcionar
Optional<Map.Entry<String, String>> result = map.entrySet().stream().max(Comparator.comparing(Map.Entry::getValue));
System.out.println(result);
la salida es
Optional[4=2014-09-09]
Esto debería proporcionar la fecha más reciente (también conocida como la más grande) en comparación con las demás.
String max = map.values().stream().reduce("0000-00-00",
(a, b) -> b.compareTo(a) >= 0 ? b
: a);
Si también desea la clave, hágalo y devuelva un Map.Entry. Requiere Java 9+
Entry<String, String> ent =
map.entrySet().stream().reduce(Map.entry("0", "0000-00-00"),
(a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
: a);
System.out.println(ent.getKey() + " -> " ent.getValue());
Esto supone que su mapa no está vacío. Si está vacío, devuelve un valor nulo. Funciona con Java 8+
Entry<String, String> ent = map.entrySet().stream().reduce(
(a, b) -> b.getValue().compareTo(a.getValue()) >= 0 ? b
: a).orElseGet(() -> null);
Puede analizar la cadena en
LocalDate
y ordenarla en orden inverso
Entry<String, String> res = map.entrySet()
.stream()
.sorted(Comparator.comparing((Entry<String, String> entry)->LocalDate.parse(entry.getValue())).reversed())
.findFirst()
.orElse(null); // if not present return null or empty Entry
Puedes hacer lo siguiente:
import java.util.Map.Entry;
Entry<String, String> maxEntry = map.entrySet()
.stream()
.max(Entry.comparingByValue());
.orElseThrow(NoSuchElementException::new);
o:
Entry<String, String> max = Collections.max(map.entrySet(), Entry.comparingByValue());
Ambos producirán el mismo resultado.
Use Collections.max con entrySet
Entry<String, String> max = Collections.max(map.entrySet(), Map.Entry.comparingByValue());
o
Entry<String, String> max = Collections.max(map.entrySet(),
new Comparator<Entry<String, String>>() {
@Override
public int compare(Entry<String, String> e1, Entry<String, String> e2) {
return LocalDate.parse(e1.getValue()).compareTo(LocalDate.parse(e2.getValue()));
}
});