英文:
Java stream filter specified variable, delete it and delete next 3 variables in row
问题
代码中是否可能找到指定的变量并删除接下来的3个迭代对象?
List<Double> hoursList = Arrays.asList(8.00, 8.15, 8.30, 8.45, 9.00, 9.15, 9.30, 9.45, 10.00, 10.15, 10.30, 10.45, 11.00);
Double visitTime = hoursList.get(4);
int n = 3;
List<Double> hours = hoursList.stream().filter(x -> !x.equals(visitTime)).collect(Collectors.toList());
这段代码只删除了列表中的一个对象 9.00,是否可能连续删除接下来的3个对象?
预期输出:
[8.00, 8.15, 8.30, 8.45, 10.00, 10.15, 10.30, 10.45, 11.00]
英文:
Is it possible to find in stream specified variable and delete the next 3 iterated objects?
List<Double> hoursList = Arrays.asList(8.00,8.15,8.30, 8.45, 9.00,9.15, 9.30, 9.45,10.00,
10.15,10.30,10.45,11.00);
Double visitTime = hoursList.get(4);
int n = 3;
List<Double> hours = hoursList.stream().filter(x -> !x.equals(visitTime)).collect(Collectors.toList());
this code just delete 1 object 9.00 from List it's possible to delete the next 3 objects in the row?
Expected output:
[8.00,8.15,8.30, 8.45,10.00,10.15,10.30,10.45,11.00]
答案1
得分: 0
如我在原始问题的评论中提到的,如果你想从 List
中删除项目,请确保将其实例化为 new ArrayList<>(Arrays.asList())
或者 new ArrayList<>(List.of())
,而不是使用 Arrays.asList()
。Arrays.asList()
返回一个固定大小的围绕 array
的包装器,直接由 array
支持。否则你将会得到一个 UnsupportedOperationException
。
话虽如此,我会使用 subList
来完成这个任务,它更加简单:
hoursList.subList(4, 4 + 3 + 1).clear();
如果你更喜欢一个能够接受参数以获得更多灵活性(并检查潜在的索引越界)的方法:
public List<Double> removeHours(List<Double> hours, double hour, int nextHours) {
int startIndex = hours.indexOf(hour);
int finalIndex = Math.min(startIndex + nextHours + 1, hours.size());
hours.subList(startIndex, finalIndex).clear();
return hours;
}
然后你可以这样做:
List<Double> hoursRemoved = removeHours(hoursList, 9.0, 3);
System.out.println(hoursRemoved);
输出
[8.0, 8.15, 8.3, 8.45, 10.0, 10.15, 10.3, 10.45, 11.0]
英文:
As I mentioned in my comment in the original question, if you want to delete items from the List
, make sure you instantiate it as new ArrayList<>(Arrays.asList())
or new ArrayList<>(List.of())
instead of Arrays.asList()
. Arrays.asList()
returns a fixed size wrapper around an array
and is directly backed by the array
. Otherwise you will get an UnsupportedOperationException
.
Having said that, I would use subList
for that job, it is much more simple:
hoursList.subList(4, 4 + 3 + 1).clear();
If you prefer a method that accepts parameters for more flexibility (and checks for potential index out of bounds):
public List<Double> removeHours(List<Double> hours, double hour, int nextHours) {
int startIndex = hours.indexOf(hour);
int finalIndex = Math.min(startIndex + nextHours + 1, hours.size());
hours.subList(startIndex, finalIndex).clear();
return hours;
}
Then you can do:
List<Double> hoursRemoved = removeHours(hoursList, 9.0, 3);
System.out.println(hoursRemoved);
Output
[8.0, 8.15, 8.3, 8.45, 10.0, 10.15, 10.3, 10.45, 11.0]
答案2
得分: 0
你可以使用两个流的串联。使用takeWhile
、dropWhile
和skip
,然后将两个流连接在一起,将会得到所期望的结果:
List<Double> hours = Stream.concat(
hoursList.stream()
.takeWhile(e -> !e.equals(visitTime)),
hoursList.stream()
.dropWhile(e -> !e.equals(visitTime))
.skip(3)
).collect(Collectors.toList());
英文:
You can use concatenation of two streams. Using takeWhile
, dropWhile
and skip
, then concat two streams together, will return desired result:
List<Double> hours = Stream.concat(
hoursList.stream()
.takeWhile(e -> !e.equals(visitTime)),
hoursList.stream()
.dropWhile(e -> !e.equals(visitTime))
.skip(3)
).collect(Collectors.toList());
答案3
得分: 0
如果元素是时间,请将它们视为时间,而不是双精度数。java.time
中的LocalTime
类,即现代Java日期和时间API,是您所需的。
List<LocalTime> hoursList = Stream.iterate(LocalTime.of(8, 0), t -> t.plusMinutes(15))
.limit(13)
.collect(Collectors.toList());
System.out.println(hoursList);
LocalTime startTime = LocalTime.of(8, 45);
LocalTime endTime = startTime.plusHours(1);
List<LocalTime> hours = new ArrayList<>(hoursList);
hours.removeIf(t -> !t.isBefore(startTime) && t.isBefore(endTime));
System.out.println(hours);
输出结果:
> [08:00, 08:15, 08:30, 08:45, 09:00, 09:15, 09:30, 09:45, 10:00, 10:15, 10:30, 10:45, 11:00]
> [08:00, 08:15, 08:30, 09:45, 10:00, 10:15, 10:30, 10:45, 11:00]
我同意Harshal Parekh的观点,使用removeIf()
比使用流操作更可读且更简单。两种选项都是可行的。为了使removeIf()
正常工作,我们需要确保我们拥有一个可修改的列表。将其复制到新的ArrayList
中可以确保这一点。
链接: Oracle教程:Date Time 解释了如何使用java.time。
英文:
If the elements are times, handle them as times, not as double numbers. The LocaTime
class of java.time, the modern Java date and time API, is what you need.
List<LocalTime> hoursList = Stream.iterate(LocalTime.of(8, 0), t -> t.plusMinutes(15))
.limit(13)
.collect(Collectors.toList());
System.out.println(hoursList);
LocalTime startTime = LocalTime.of(8, 45);
LocalTime endTime = startTime.plusHours(1);
List<LocalTime> hours = new ArrayList<>(hoursList);
hours.removeIf(t -> ! t.isBefore(startTime) && t.isBefore(endTime));
System.out.println(hours);
Output:
> [08:00, 08:15, 08:30, 08:45, 09:00, 09:15, 09:30, 09:45, 10:00, 10:15, 10:30, 10:45, 11:00]
> [08:00, 08:15, 08:30, 09:45, 10:00, 10:15, 10:30, 10:45, 11:00]
I agree with Harshal Parekh that it’s more readable and simpler to use removeIf()
than a stream operation. Both options are possible. For removeIf()
to work we need to make sure that we have got a modifiable list. Copying into a new ArrayList
ensures this.
Link: Oracle tutorial: Date Time explaining how to use java.time.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论