我使用传统的for循环编写了一段代码,如下所示。我想重构它以使用java 8流并删除for循环。以下代码的输出应为3,因为这是最长的连续数字列表(4,5和6)
List<Integer> weekDays = Lists.newArrayList(1, 2, 4, 5, 6);
List<Integer> consecutiveIntervals = Lists.newArrayList();
int maxConsecutiveTillNow = 1;
for (int i = 1; i < weekDays.size(); i++) {
if (weekDays.get(i) - weekDays.get(i - 1) == 1) {
maxConsecutiveTillNow++;
} else {
consecutiveIntervals.add(maxConsecutiveTillNow);
maxConsecutiveTillNow = 1;
}
}
consecutiveIntervals.add(maxConsecutiveTillNow);
System.out.println(consecutiveIntervals.stream()
.max(Integer::compareTo)
.get()
);
答案 0 :(得分:5)
foreach (var item in CourseId)
{
var cr = new Courses();
cr.ID = item;
// Here:
db.Entry(cr).State = EntityState.Unchanged;
// or alternatively:
// db.Courses.Attach(cr);
rec.course.Add(cr);
}
db.Admins.Add(rec);
db.SaveChanges();
API不太适合此类问题。几乎不可能以正确的方式跟踪Stream
的所见元素。所以你必须选择多个Stream
。
基于Stuart Marks'个答案之一。
Streams
输出
3
答案 1 :(得分:3)
溪流的想法是相互独立地处理流中的项目。该模式的最大好处是可以并行执行,因为流API的设计是并发的(即,您不应该在流的顺序项的处理之间保持状态)。在您的特定任务中,数组的使用是最合适的。
答案 2 :(得分:3)
创建序列列表并将其排序为所有序列列表中的最长序列。
例如,如果有列表[1,2,4,5,6] ,则将其分解为:
[[1,2],[4,5,6]]
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
public class NumberSequence {
public static void main(String[] args) {
List<Integer> weekDays = Arrays.asList(1, 2, 4, 5, 6);
List<List<Integer>> allWeekdaySequences = weekDays.stream()
.collect(
(Supplier<List<List<Integer>>>) ArrayList::new,
(sequences, currentElement) -> generateCombinedBatchesFor(sequences, currentElement),
List::addAll);
System.out.println(allWeekdaySequences);
Optional<List<Integer>> longestSequence = allWeekdaySequences.stream()
.sorted((seq1, seq2) -> seq2.size() - seq1.size())
.findFirst();
System.out.println(longestSequence.isPresent() ? longestSequence.get().size() : "Nothing found!!");
}
private static void generateCombinedBatchesFor(List<List<Integer>> sequences, Integer currentElement) {
if (needsNewSequence(sequences, currentElement)) {
sequences.add(new ArrayList<>());
}
getLastSequence(sequences).add(currentElement);
}
private static boolean needsNewSequence(List<List<Integer>> sequences, Integer currentElement) {
return sequences.size() == 0 || !isConsecutiveDay(getLastElement(getLastSequence(sequences)),
currentElement);
}
private static boolean isConsecutiveDay(Integer lastElement, Integer currentElement) {
return currentElement - lastElement == 1;
}
private static Integer getLastElement(List<Integer> lastSequence) {
return !lastSequence.isEmpty() ? lastSequence.get(lastSequence.size()-1) : -1;
}
private static List<Integer> getLastSequence(List<List<Integer>> sequences) {
return sequences.get(sequences.size()-1);
}
}
<强>输出强>
3
答案 3 :(得分:2)
为此,您需要部分缩减(批处理),java 8流API不提供。
您可以通过分裂器(类似于this answer)自行实现,也可以使用提供它的库,例如streamex或proton-pack
答案 4 :(得分:2)
如果您不介意使用第三方库,我可能会推荐我的免费StreamEx库,它增强了标准的Stream API,并为操作员提供部分缩减功能:
StreamEx.of(weekDays)
.collapse((a, b) -> b - a == 1, Collectors.counting())
.max(Comparator.naturalOrder())
此处collapse是部分缩减运算符。第一个BiPredicate
告诉给定的相邻元素对是否应该一起还原或新的还原组应该开始。这里的规则是相邻元素应该相差1.第二个参数是用于执行简化的收集器(这里只是counting()
收集器)。所以在collapse
之后我们得到了组长度流(输入为2和3)。最后,我们使用标准max()
运算符。
StreamEx库与Stream API完全兼容(StreamEx创建的Stream可以用作普通流)。 collapse
运算符是懒惰的,非常快且并行友好。