Java流过滤指定变量,删除该变量以及连续的下3个变量。

huangapple go评论64阅读模式
英文:

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&lt;Double&gt; 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&lt;Double&gt; hours = hoursList.stream().filter(x -&gt; !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&lt;&gt;(Arrays.asList()) 或者 new ArrayList&lt;&gt;(List.of()),而不是使用 Arrays.asList()Arrays.asList() 返回一个固定大小的围绕 array 的包装器,直接由 array 支持。否则你将会得到一个 UnsupportedOperationException

话虽如此,我会使用 subList 来完成这个任务,它更加简单:

hoursList.subList(4, 4 + 3 + 1).clear();

如果你更喜欢一个能够接受参数以获得更多灵活性(并检查潜在的索引越界)的方法:

public List&lt;Double&gt; removeHours(List&lt;Double&gt; 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&lt;Double&gt; 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&lt;&gt;(Arrays.asList()) or new ArrayList&lt;&gt;(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&lt;Double&gt; removeHours(List&lt;Double&gt; 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&lt;Double&gt; 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

你可以使用两个流的串联。使用takeWhiledropWhileskip,然后将两个流连接在一起,将会得到所期望的结果:

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&lt;Double&gt; hours = Stream.concat(
            hoursList.stream()
                    .takeWhile(e -&gt; !e.equals(visitTime)),
            hoursList.stream()
                    .dropWhile(e -&gt; !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&lt;LocalTime&gt; hoursList = Stream.iterate(LocalTime.of(8, 0), t -&gt; t.plusMinutes(15))
			.limit(13)
			.collect(Collectors.toList());
	System.out.println(hoursList);
	
	LocalTime startTime = LocalTime.of(8, 45);
	LocalTime endTime = startTime.plusHours(1);
	List&lt;LocalTime&gt; hours = new ArrayList&lt;&gt;(hoursList);
	hours.removeIf(t -&gt; ! t.isBefore(startTime) &amp;&amp; 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.

huangapple
  • 本文由 发表于 2020年7月26日 07:06:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63094473.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定