如何使用lambda表达式计算整数列表中的差异

时间:2015-06-07 19:21:47

标签: java lambda java-8 java-stream

让我说我有以下数组:{1,2,3,4,6,7,8}放在Stream<Integer> s = Stream.of(1,2,3,4,6,7,8);

如何在Java lambda表达式和Stream函数中使用来计算每个元素与下一个元素之间的差异(在本例中为{1,1,1,2,1,1})? 这不是真正的reduce操作,因为reduce将整个列表转换为1个元素;它也不是一个地图操作,因为它需要两个元素来计算差异,而不仅仅是一个。

5 个答案:

答案 0 :(得分:6)

您可以遍历索引而不是元素,例如

int s[] = {1, 2, 3, 4, 6, 7, 8};
IntStream differences = 
    IntStream.range(0, s.length - 1)
        .map(i -> s[i + 1] - s[i]);

答案 1 :(得分:2)

另一个答案似乎已被接受,但有一个想法所以我无论如何都要发布。您可以将 <?php $idd = intval($_GET['idd']); require_once('db_con.php'); //$sq="select id from questions"; //$q_id = (isset($_GET['id']) ? intval($_GET['id']) : 1); //static $r=1; //static $q_id=0; //$q_id++; $sql="SELECT * FROM questions where id= '".$idd."'"; //$sql="SELECT * FROM questions WHERE id =$r"; $result = mysql_query($sql); /* echo "<table> <tr> <th>Question</th> <th>Option1</th> <th>Option2</th> <th>Option3</th> <th>Next</th> </tr>"; */ while($row = mysql_fetch_array($result)) { // echo "<tr>"; echo "<h2>"; echo $row['question']; echo "</h2>" ; // echo "<br>" . $row['option1'] ; // echo "<td>" . $row['option2'] . "</td>"; // echo "<td colspan='2'>" . $row['option3'] . "</td>"; // echo "</tr>"; } //echo "</table>"; mysql_close($conn); ?> </body> </html> 直接收集到另一个Collector

然后你可以这样写:

Stream<Integer>

这是我写的一个实现:

s.collect(intDifferences()).forEach(d -> System.out.print(d + ","));

答案 2 :(得分:1)

如果允许映射函数产生副作用,则可以使用map(),即您可以存储对流中前一个对象的引用:

Stream.of(1, 2, 3, 4, 6, 7, 8)
    .map(new Function<Integer, Optional<Integer>>() {
        Optional<Integer> previousValue = Optional.empty();
        @Override
        public Optional<Integer> apply(Integer current) {
            Optional<Integer> value = previousValue.map(previous -> current - previous);
            previousValue = Optional.of(current);
            return value;
        }
    })
    .filter(Optional::isPresent)
    .map(Optional::get)
    .forEach(System.out::println);

请注意,此实现不是pure function,因此您必须小心它的使用方式。上面的示例有效,因为每次都会实例化该函数(特别是,每次使用都会重置previousValue)。但是,如果代码被重构,它将工作,以便函数存储在局部变量中,因为第二次使用该函数时,previousValue将不为空。因此,通常不鼓励这种实施。

答案 3 :(得分:1)

您可以使用我的StreamEx库专门针对此案例采用pairMap方法:

StreamEx<Integer> s = StreamEx.of(1,2,3,4,6,7,8);
s = s.pairMap((a, b) -> b-a);
s.forEach(System.out::println);

StreamEx类实现Stream并与之完全兼容。同样的事情也适用于原始流:

IntStreamEx s = IntStreamEx.of(1,2,3,4,6,7,8);
s = s.pairMap((a, b) -> b-a);
s.forEach(System.out::println);

答案 4 :(得分:0)

public int[] diff(int... input) {
    AtomicInteger aInt = new AtomicInteger();
    return IntStream.of(input).map(v -> v - aInt.getAndSet(v)).skip(1).toArray();
}

不是纯函数,因为它会更改AtomicInteger的状态