這個想法是從陣列 Person 型別回傳第二個最年輕的人。我有這個,但不知道這是否是最好的解決方案,您如何看待這種方法?或者解決這個問題的另一個好主意。感謝任何建議
這是課程:
public class Persona {
private String nombre;
private Integer edad;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Integer getEdad() {
return edad;
}
public void setEdad(Integer edad) {
this.edad = edad;
}
public Persona(String nombre, Integer edad) {
this.nombre = nombre;
this.edad = edad;
}
}
以及使回傳的方法也是一個帶有示例值的串列(我只是對串列進行排序,然后使用過濾器退出具有第一個值的人,然后使用新的第一個值進行過濾以僅保存該值)
public static void main(String[] args) {
ArrayList<Persona> listaPrueba = new ArrayList<Persona>();
listaPrueba.add(new Persona("Patricia", 21));
listaPrueba.add(new Persona("Juan", 22));
listaPrueba.add(new Persona( "Ana", 45));
listaPrueba.add(new Persona("John", 22));
listaPrueba.add(new Persona( "Max", 21));
listaPrueba.add(new Persona("Peter", 50));
segundoMayor(listaPrueba).stream().forEach(item -> System.out.println(item.getNombre() " " item.getEdad()));
}
public static List<Persona> segundoMayor(ArrayList<Persona> lista){
lista.sort(Comparator.comparing(Persona::getEdad));
List<Persona> listaFiltrada = lista.stream().filter(item -> !item.getEdad().equals(lista.get(0).getEdad())).collect(Collectors.toList());
return listaFiltrada.stream().filter(item -> item.getEdad().equals(listaFiltrada.get(0).getEdad())).collect(Collectors.toList());
}
輸出應該是:
胡安 22 約翰 22
uj5u.com熱心網友回復:
我目前沒有我的 Java IDE 設定,所以認為這是偽代碼(并撰寫你自己的單元測驗來檢查錯誤)。但我的解決方案是迭代Persona物件串列以查找第二年輕的年齡,然后再次迭代串列以查找具有該年齡的所有物件。然后,您可以將匹配Persona的物件添加到集合中,和/或將它們列印到控制臺。
int youngestAge = 1000, secondYoungestAge = 1000;
for (Persona p : listaPrueba) {
int edad = p.getEdad();
if (edad < youngestAge) {
secondYoungestAge = youngestAge;
youngestAge = edad;
} else if (edad < secondYoungestAge) {
secondYoungestAge = edad;
}
}
if (secondYoungestAge == 1000) {
throw new NoSuchElementException("No matching Persona!");
}
List<Persona> secondYoungestPersona = new ArrayList<>();
for (Persona p : listaPrueba) {
int edad = p.getEdad();
if (edad == secondYoungestAge) {
secondYoungestPersona.add(p);
// AND/OR write the name and age to console
System.out.print(p.getNombre() " " edad " ");
}
}
這應該比使用 a TreeMap(按年齡排序)或對整個排序ArrayList(因為您不關心其余專案的順序,您只關心第二年輕的專案)更有效。但如果您需要確定,那么請仔細撰寫 JMH 基準測驗來測驗這三種方法。
uj5u.com熱心網友回復:
非常有趣。
我用流寫了一個解決方案。也許,它沒有最好的性能,但它具有很高的可讀性。
public static List<Persona> segundoMayor(final ArrayList<Persona> lista) {
// first, sort it by age
final var sorted = lista
.stream()
.sorted(Comparator.comparing(Persona::getEdad))
.toList();
// now, find the second youngest age
final int secondYoungestAge = sorted
.stream()
.map(Persona::getEdad)
.distinct()
.skip(1)
.findFirst()
.orElse(0);
// at the end: only take the youngest
// and second youngest with takeWhile (so we can reduce the iterations)
// and filter them for the second youngest age
return sorted
.stream()
.takeWhile(persona -> persona.getEdad() <= secondYoungestAge)
.filter(persona -> persona.getEdad() == secondYoungestAge)
.toList();
}
uj5u.com熱心網友回復:
我更喜歡像這樣在陣列的單個決議中找到串列
public static List<Persona> segundoMayor(List<Persona> lista){
lista.sort(Comparator.comparing(Persona::getEdad));
Persona first = lista.get(0), second = null;
List<Persona> secondRankList = new ArrayList<>();
for(Persona persona: lista) {
if(second == null && persona.getEdad() > first.getEdad()) {
second = persona;
}
if(second != null && second.getEdad().equals(persona.getEdad())) {
secondRankList.add(persona);
} else if(second != null && !second.getEdad().equals(persona.getEdad())){
break;
}
}
return secondRankList;
}
uj5u.com熱心網友回復:
一種主要功能性的方法:
private static List<Persona> segundoMayor(List<Persona> lista){
return lista
.stream()
.collect(Collectors.groupingBy(Persona::getEdad))
.entrySet()
.stream()
.sorted(Comparator.comparing(Entry::getKey))
.map(Entry::getValue)
.skip(1)
.findFirst()
.orElse(Collections.emptyList()); // or orElse(List.of());
// or orElsehrow();
基本上:
- 按年齡分組
Map<Integer, List<Persona>> - 按年齡對組進行排序
- 提取
Persona每個年齡的串列 - 跳過第一個串列(所以第二個最年輕的就是下一個)
- 獲取流中剩余的第一個串列
- 如果沒有可用,則生成一個空串列
在輸入串列不包含至少兩個不同年齡的情況下,替換orElse為orElseThrow拋出 a而不是回傳空串列。NoSuchElementExceptionPersona
這可能不是最有效的方法:為所有年齡段創建地圖,但另一方面,排序更少的元素(每個年齡段一個條目)。
uj5u.com熱心網友回復:
通常,人們會使用堆來有效地找到n 個最小的元素。
- 創建一個與所需順序相反的堆(在本例中為最大堆)。
- 對于每個元素,
- 將元素添加到堆中;
- 如果堆有超過n 個專案,則移除堆的頂部。
使用這種方法,如果最小元素的關系超過n 個,您將獲得您查看的前n 個結果。
這種情況有點不同,因為您想找到與第 n 個最小屬性相關的元素數量不受限制。這需要一些額外的步驟。
首先,您可以構建一個通用的“熱門”收集器以用于流:
/**
* @param limit the maximum number of items to collect
* @param order a function to establish item ordering
* @param <T> the type of items to collect
* @return a collector for a limited number of items ordered <em>last</em>
*/
public static <T> Collector<T, ?, List<T>> top(int limit, Comparator<? super T> order) {
Objects.requireNonNull(order);
Supplier<Queue<T>> supplier = () -> new PriorityQueue<>(order);
BiConsumer<Queue<T>, T> accumulator = (q, e) -> {
q.add(e);
if (q.size() > limit) q.remove();
};
BinaryOperator<Queue<T>> combiner = (q1, q2) -> {
q2.forEach(e -> accumulator.accept(q1, e));
return q1;
};
Function<Queue<T>, List<T>> finisher = q -> {
List<T> list = new ArrayList<>(q.size());
while (!q.isEmpty()) list.add(q.remove());
Collections.reverse(list);
return list;
};
return Collector.of(supplier, accumulator, combiner, finisher);
}
/**
* @param limit the maximum number of items to collect
* @param order a function to establish item ordering
* @param <T> the type of items to collect
* @return a collector for a limited number of items ordered <em>first</em>
*/
public static <T> Collector<T, ?, List<T>> bottom(int limit, Comparator<? super T> order) {
return top(limit, order.reversed());
}
現在您可以將它應用到您的案例中,并進行一些額外的處理。首先,過濾每個人的年齡,只考慮不同的非空值。第二低的年齡(如果存在)然后在第二次通過輸入時用作過濾器。
List<Persona> secondYoungest(Collection<Persona> personas) {
List<Integer> youngest = personas.stream()
.map(Persona::getEdad)
.filter(Objects::nonNull)
.distinct()
.collect(bottom(2, Integer::compare));
if (youngest.size() != 2) {
throw new IllegalArgumentException("Second youngest age is undefined");
}
Integer age = youngest.get(1);
return personas.stream()
.filter(p -> age.equals(p.getEdad()))
.collect(Collectors.toList());
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/482219.html
