假设我有一个List<<LogFormat>Log>
像这样:
[Log(name = a, accessTime = 5),
Log(name = a, accessTime = 4),
Log(name = a, accessTime = 3),
Log(name = b, accessTime = 10),
Log(name = b, accessTime = 9),
Log(name = c, accessTime = 2),
...]
我想在每个accessTime
中保留name
的最大值,就像这样:
[Log(name = a, accessTime = 5),
Log(name = b, accessTime = 10),
...]
但是我不知道列表中有多少name
个,因此我尝试编写一个循环:
for (LogFormat s : Log) {
for (LogFormat t : Log) {
if (s.getName().equals(t.getName())
&& s.getAccessTime() > t.getAccessTime()) {
Log.remove(t);
}
}
}
但是似乎我无法循环使用.remove()
,如何解决此问题?
答案 0 :(得分:0)
您可以使用带有索引的嵌套循环,然后在删除某些内容时从索引中减去:
for (int i = 0; i < s.size() - 1; i++) {
for (int j = i + 1; j < s.size(); j++) {
if (...) {
s.remove(j--)
}
}
}
您还需要考虑其他方法(例如,是否需要删除第一个元素)。
但是,我认为最好的解决方案是使用Map,如果适用的话,存储每个日志的最大值。
答案 1 :(得分:0)
尝试一下:
package com.example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
static class Log{
private int accessTime;
private String name;
Log( String name,int accessTime){
this.accessTime = accessTime;
this.name = name;
}
public int getAccessTime(){
return this.accessTime;
}
public String getName(){
return this.name;
}
@Override
public String toString(){
return "{ name = " + name +", accessTime = " + accessTime + "}";
}
}
public static void main(String[] args) {
List<Log> l = new ArrayList<>();
l.add(new Log("a", 5));
l.add(new Log("a", 4));
l.add(new Log("a", 3));
l.add(new Log("b", 10));
l.add(new Log("b", 9));
l.add(new Log("c", 2));
Map<String, Log> m = new HashMap<>();
l.stream().forEach( log -> {
String name = log.getName();
int accessTime = log.getAccessTime();
if(m.containsKey(name)){
if(m.get(name).getAccessTime() < accessTime) {
m.put(name, log);
}
} else {
m.put(name, log);
}
});
List<Log> valueList = new ArrayList<>(m.values());
System.out.println(valueList);
}
}
输出:
[{name = a,accessTime = 5},{name = b,accessTime = 10},{name = c,accessTime = 2}]
答案 2 :(得分:0)
此带有冒号的 foreach循环是具有“删除”功能的迭代器的语法糖。因此,如果您想以这种方式使用迭代器,则基本上需要访问它:
List<Log> list = new ArrayList<>(Arrays.asList(new Log("a", 1), new Log("b", 5), new Log("a", 4), new Log("b", 2) ));
for (Iterator<Log> it = list.iterator(); it.hasNext(); ) {
Log currlog = it.next();
it.remove();
}
为了存储具有最大访问时间的日志名称,您可以使用辅助哈希映射并保留每个名称的最大值,并在迭代过程中根据需要对其进行更新
答案 3 :(得分:0)
我会解决这个问题。您的目标是:
我想在每个
accessTime
中保留name
的最大值
Map
非常适合这些要求。 name
将充当键,而最大的accessTime
将是地图的值。
因此,给定类:
class Log {
String name;
int accessTime;
public String getName() {
return name;
}
public int getAccessTime() {
return accessTime;
}
}
还有一个Log
的列表,称为logs
。
您只需要将收集器toMap()
与Math::max
用作合并函数:
Map<String, Integer> maxAccessTimeByName = logs.stream()
.collect(Collectors.toMap(Log::getName, Log::getAccessTime, Math::max));
Math::max
确保在发生冲突时选择最大值,即同一键至少出现两次。
现在,您可以按名称访问最长访问时间:
int maxAccessTimeForA = maxAccessTimeByName.get("a");