标签: java-stream

带有spring注释方法的Java .parallelStream()

我尝试使用parallelStream()带有Spring @Transactional注释的DAO 并得到这样的问题:

@Transactional
public void processCollection(Collection<Object> objects) {
    objects.parallelStream()
            .forEach(this::processOne);  //throw exception
}

@Transactional
public void processOne(Object o) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

工作正确:

@Transactional
public void processCollection(Collection<Object> objects) {
    objects.stream()
            .forEach(this::processOne);  //work correctly
}

@Transactional
public void processOne(Object o) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

例外:

org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:978)
Run Code Online (Sandbox Code Playgroud)

我如何使用带@Transactional注释的方法parallelStream()?

更新 为什么会发生这种情况Spring事务管理器和多线程 但是我希望Spring 4支持java 8可以为此提供一些解决方案.有任何想法吗?

java spring multithreading java-8 java-stream

13
推荐指数
2
解决办法
6139
查看次数

java 8嵌套流

假设你有这样的结构类:

public class Review{
    private Integer idReview;
    private String description;
    private ArrayList<RelReviewImage> images;
}

public class RelReviewImage{
    private Integer idRelReviewImage;
    private Integer idImage;
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

使用Java 8和Streams,我们希望对对象进行过滤idImage并返回Review对象.
可能吗?一个级别很容易,但是我们找不到任何示例或文档的2个级别.

lambda java-8 java-stream

13
推荐指数
2
解决办法
2万
查看次数

如何以相反的顺序对IntStream进行排序

我正在使用.txt文件读取数字BufferedReader.我想颠倒这种蒸汽中元素的顺序,这样当它们被收集时,它们将从最高到最低排列.我不想在构建数组后进行排序,因为我不知道它中可能有多少个元素,我只需要最高的N个元素.

in = new BufferedReader(reader);
                int[] arr = in.lines()
                        .mapToInt(Integer::parseInt)
                        .sorted()
                        .limit((long) N)
                        .toArray();
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

13
推荐指数
2
解决办法
7457
查看次数

在Stream reduce方法中,对于sum,标识总是0,对于乘法,1必须是1?

我继续学习java 8.

我发现了有趣的行为:

让我们看看代码示例:

// identity value and accumulator and combiner
        Integer summaryAge = Person.getPersons().stream()
                //.parallel()  //will return surprising result
                .reduce(1, (intermediateResult, p) -> intermediateResult + p.age,
                        (ir1, ir2) -> ir1 + ir2);
        System.out.println(summaryAge);
Run Code Online (Sandbox Code Playgroud)

和模型类:

public class Person {

    String name;

    Integer age;
    ///...

    public static Collection<Person> getPersons() {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Vasya", 12));
        persons.add(new Person("Petya", 32));
        persons.add(new Person("Serj", 10));
        persons.add(new Person("Onotole", 18));
        return persons;
   }
}
Run Code Online (Sandbox Code Playgroud)

12 + 32 + 10 + 18 = 72
对于序列流,此代码始终返回73(72 …

java reduce java-8 java-stream

13
推荐指数
3
解决办法
6357
查看次数

按Java 8中的Map列表分组

我有一个像这样的列表:

List<Map<String, Long>>
Run Code Online (Sandbox Code Playgroud)

有没有办法,使用lambda,将此列表转换为:

Map<String, List<Long>>
Run Code Online (Sandbox Code Playgroud)

例:

Map<String, Long> m1 = new HashMap<>();
m1.put("A", 1);
m1.put("B", 100);

Map<String, Long> m2 = new HashMap<>();
m2.put("A", 10);
m2.put("B", 20);
m2.put("C", 100);

List<Map<String, Long>> beforeFormatting = new ArrayList<>();
beforeFormatting.add(m1);
beforeFormatting.add(m2);
Run Code Online (Sandbox Code Playgroud)

格式化后:

Map<String, List<Long>> afterFormatting;
Run Code Online (Sandbox Code Playgroud)

看起来像是这样的:

A -> [1, 10]
B -> [100, 20]
C -> [100]
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream

13
推荐指数
1
解决办法
5754
查看次数

在并行流上调用顺序会使所有先前的操作顺序进行

我有一个重要的数据集,并希望调用缓慢但干净的方法,而不是调用快速方法,副作用对第一个结果.我对中间结果不感兴趣,所以我不想收集它们.

显而易见的解决方案是创建并行流,进行慢速呼叫,再次使流顺序,并进行快速呼叫.问题是,所有代码都在单线程中执行,没有实际的并行性.

示例代码:

@Test
public void testParallelStream() throws ExecutionException, InterruptedException
{
    ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);
    Set<String> threads = forkJoinPool.submit(()-> new Random().ints(100).boxed()
            .parallel()
            .map(this::slowOperation)
            .sequential()
            .map(Function.identity())//some fast operation, but must be in single thread
            .collect(Collectors.toSet())
    ).get();
    System.out.println(threads);
    Assert.assertEquals(Runtime.getRuntime().availableProcessors() * 2, threads.size());
}

private String slowOperation(int value)
{
    try
    {
        Thread.sleep(100);
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }
    return Thread.currentThread().getName();
}
Run Code Online (Sandbox Code Playgroud)

如果我删除sequential,代码按预期执行,但显然,非并行操作将在多个线程中调用.

你能推荐一些关于这种行为的引用,或者某些方法可以避免临时收集吗?

java multithreading forkjoinpool java-stream

13
推荐指数
1
解决办法
2566
查看次数

如何在Stream上重用过滤器和地图的应用程序?

我有一组从共享类型(即继承域对象的GroupRecord extends Record,RequestRecord extends Record).亚型具有特定属性(即GroupRecord::getCumulativeTime,RequestRecord::getResponseTime).

此外,由于解析日志文件,我有一个混合子类型的记录列表.

List<Record> records = parseLog(...);
Run Code Online (Sandbox Code Playgroud)

为了计算日志记录的统计数据,我想仅在与特定子类型匹配的记录子集上应用数学函数,即仅在GroupRecords上.因此,我希望有一个特定子类型的过滤流.我知道我可以使用一个filter和map一个子类型

records.stream()
       .filter(GroupRecord.class::isInstance)
       .map(GroupRecord.class::cast)
       .collect(...
Run Code Online (Sandbox Code Playgroud)

在流上多次应用此过滤器和强制转换(特别是对于不同的计算多次执行相同的子类型时)不仅繁琐,而且会产生大量重复.

我目前的做法是使用a TypeFilter

class TypeFilter<T>{

    private final Class<T> type;

    public TypeFilter(final Class<T> type) {
        this.type = type;
    }

    public Stream<T> filter(Stream<?> inStream) {
        return inStream.filter(type::isInstance).map(type::cast);
    }
}
Run Code Online (Sandbox Code Playgroud)

要应用于流:

TypeFilter<GroupRecord> groupFilter = new TypeFilter(GroupRecord.class); 

SomeStatsResult stats1 = groupFilter.filter(records.stream())
                                      .collect(...)
SomeStatsResult stats2 = groupFilter.filter(records.stream())
                                      .collect(...)
Run Code Online (Sandbox Code Playgroud)

它有效,但我发现这种方法对于这么简单的任务来说有点多了.因此我想知道,使用流和函数以简洁和可读的方式使这种行为可重用是否有更好或更好的方法是什么?

java java-8 java-stream

13
推荐指数
2
解决办法
1696
查看次数

使用Collectors.summingInt时如何获取自定义类型而不是Integer?

我目前正在创建一个Map<String, Map<LocalDate, Integer>>这样的Integer代表秒:

Map<String, Map<LocalDate, Integer>> map = stream.collect(Collectors.groupingBy(
            x -> x.getProject(),
            Collectors.groupingBy(
                x -> x.getDate(),
                Collectors.summingInt(t -> t.getDuration().toSecondOfDay())
            )
        ));
Run Code Online (Sandbox Code Playgroud)

我怎么能创建一个Map<String, Map<LocalDate, Duration>>?

java grouping java-8 java-stream collectors

13
推荐指数
1
解决办法
240
查看次数

使用流API将字符串全部设置为小写但首字母大写

我有一个List<String>只通过使用流API我将所有字符串设置为小写,将它们从最小的字符串排序到最大字符串并打印它们.我遇到的问题是将字符串的第一个字母大写.

这是我做的事.stream().map()吗?

public class Main {

    public static void main(String[] args) {

        List<String> list = Arrays.asList("SOmE", "StriNgs", "fRom", "mE", "To", "yOU");
        list.stream()
            .map(n -> n.toLowerCase())
            .sorted((a, b) -> a.length() - b.length())
            .forEach(n -> System.out.println(n));;

    }

}
Run Code Online (Sandbox Code Playgroud)

输出:

me
to
you
some
from
strings
Run Code Online (Sandbox Code Playgroud)

期望的输出:

Me
To
You
Some
From
Strings
Run Code Online (Sandbox Code Playgroud)

java mapping capitalization java-8 java-stream

13
推荐指数
2
解决办法
664
查看次数

为什么LongSummaryStatistics实现IntConsumer?

为什么还有LongSummaryStatistics实现的IntConsumer时候IntSummaryStatistics实现IntConsumer?

java java-8 java-stream

13
推荐指数
1
解决办法
472
查看次数