标签: java-stream

Java 8/JDK8 Stream的函数Map/Reduce将List <String>分组为Map <String,List <String >>

Java 8即将发布......在学习Streams的过程中,我进入了一个关于使用一种新方法对字谜进行分组的场景.我面临的问题是我找不到使用map/reduce函数对Strings对象进行分组的方法.相反,我必须创建一个与http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html中记录的类似的方式.

根据文档,我们可以简单地使用LIST.stream().collect(Collectors.groupingBy(POJO :: GET_METHOD)),这样Collectors.groupingBy()将根据使用的方法聚合地图的键.但是,这种方法似乎很难包装简单的String表示.

public class AnagramsGrouping {

  static class Word {

    public String original;

    public Word(String word) {
      original = word;
    }

    public String getKey() {
      char[] characters = input.toCharArray();
      Arrays.sort(characters);
      return new String(characters);
    }

    public String toString() {
      return original;
    };
  }

  public static void main(String[] args) {
    List<Word> words = Arrays.asList(new Word("pool"), new Word("loop"), 
         new Word("stream"), new Word("arc"), new Word("odor"),
         new Word("car"), new Word("rood"), new Word("meats"),
         new Word("fires"), new Word("fries"), new Word("night"),
         new Word("thing"), …
Run Code Online (Sandbox Code Playgroud)

java mapreduce anagram java-8 java-stream

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

Files.lines在Java8中跳过断行

我正在使用Files.lines(...)读取一个非常大的(500mb)文件.它读取文件的一部分,但在某些时候它会破坏java.io.UncheckedIOException:java.nio.charset.MalformedInputException:输入长度= 1

我认为该文件具有不同字符集的行.有没有办法跳过这些断线?我知道返回的流是由Reader支持的,读者我知道如何跳过,但不知道如何从流中获取Reader以便按我喜欢的方式设置它.

    List<String> lines = new ArrayList<>();
    try (Stream<String> stream = Files.lines(Paths.get(getClass().getClassLoader().getResource("bigtest.txt").toURI()), Charset.forName("UTF-8"))) {
        stream
            .filter(s -> s.substring(0, 2).equalsIgnoreCase("aa"))
            .forEach(lines::add);
    } catch (final IOException e) {
        // catch
    }
Run Code Online (Sandbox Code Playgroud)

java file java-8 java-stream

10
推荐指数
1
解决办法
7582
查看次数

如何使用Lambda Expression获得单词平均长度

我有一个单词列表文本文件,我想从该文件中获取最小,最大和平均单词长度.

我有一个流方法:

public static Stream<String> readWords(String filename) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        Stream<String> stringStream = reader.lines();
        return stringStream;
    } catch (IOException exn) {
        return Stream.<String>empty();
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的主要测试方法中,我打印最大和最小

System.out.println(readWords(filename)
        .min(Comparator.comparing(s -> s.length()))
        .get()
        .length()
);
System.out.println(readWords(filename)
        .max(Comparator.comparing(s -> s.length()))
        .get()
        .length()
);
Run Code Online (Sandbox Code Playgroud)

它按预期工作.

问题:
是否有可能像我在min和max中那样得到单词长度的平均值?在是或否的情况下,如何做到这一点(仅作为Lambda表达式)?

java lambda java-8 java-stream

10
推荐指数
3
解决办法
2564
查看次数

Java 8 Streams - Iterator根据条件映射和删除

我试图弄清楚如何重写这个以使用流和过滤器来缩小我的标准并在必要时从地图中删除.

Iterator<Map.Entry<String,Object>> iter = listOfPossibleParams.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry<String,Object> entry = iter.next();
    if(entry.getValue() instanceof String) {
        if (StringUtils.isBlank((String) entry.getValue())) {
            iter.remove();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我最初在想这样的事情,但它显然不起作为语法错误:

listOfPossibleParams.entrySet()
            .stream()
            .filter(p -> p.getValue() instanceof String)
            .removeIf(e -> StringUtils.isBlank((String)e.getValue()));
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

10
推荐指数
1
解决办法
3819
查看次数

如果不存在,java 8将ListB的所有元素合并到ListA中

我需要将listB的所有元素合并到另一个列表listA中.

如果listA中已存在一个元素(基于自定义相等检查),我不想添加它.

我不想使用Set,我不想重写equals()和hashCode().

原因是,我不想在listA本身防止重复,我只想在listB中已经存在我认为相等的元素时才从listB合并.

我不想重写equals()和hashCode(),因为这意味着我需要确保,我在各种情况下对元素的equals()实现都有.然而,可能是listB中的元素未完全初始化,即它们可能会遗漏一个对象id,其中可能存在于listA的元素中.

我目前的方法涉及一个接口和一个实用功能:

public interface HasEqualityFunction<T> {

    public boolean hasEqualData(T other);
}

public class AppleVariety implements HasEqualityFunction<AppleVariety> {
    private String manufacturerName;
    private String varietyName;

    @Override
    public boolean hasEqualData(AppleVariety other) {
        return (this.manufacturerName.equals(other.getManufacturerName())
            && this.varietyName.equals(other.getVarietyName()));
    }

    // ... getter-Methods here
}


public class CollectionUtils {
    public static <T extends HasEqualityFunction> void merge(
        List<T> listA,
        List<T> listB) {
        if (listB.isEmpty()) {
            return;
        }
        Predicate<T> exists
            = (T x) -> {
                return listA.stream().noneMatch(
                        x::hasEqualData); …
Run Code Online (Sandbox Code Playgroud)

java collections java-8 java-stream

10
推荐指数
1
解决办法
2085
查看次数

在处理Java 8流管道时,对顺序()和并行()的调用顺序是否重要?

调用sequential()和parallel()更改Java 8流管道的执行方式是否放置?

例如,假设我有这样的代码:

new ArrayList().stream().parallel().filter(...).count();
Run Code Online (Sandbox Code Playgroud)

在这个例子中,很明显filter()将并行运行.但是,如果我有这个代码怎么办:

new ArrayList().stream().filter(...).parallel().count();
Run Code Online (Sandbox Code Playgroud)

是否filter()在并行运行仍然还是它按顺序运行?之所以不清楚是因为中间操作filter()是懒惰的,即它们不会在调用终端操作之前运行count().因此,在count()调用时,我们有一个并行流管道但是filter()顺序执行,因为它在调用之前到来了parallel()?

java parallel-processing java-stream

10
推荐指数
1
解决办法
457
查看次数

为什么Stream <T> collect方法返回不同的键顺序?

我有这个代码:

public enum Continent {ASIA, EUROPE}

public class Country {      
   private String name;
   private Continent region;

    public Country (String na, Continent reg) { 
        this.name = na;
        this.region = reg;
    }
    public String getName () {return name;} 
    public Continent getRegion () {return region;}
    @Override
    public String toString() {
        return "Country [name=" + name + ", region=" + region + "]";
    }
}
Run Code Online (Sandbox Code Playgroud)

在主要班级:

public static void main(String[] args) throws IOException {
        List<Country> couList = Arrays.asList(
            new Country ("Japan", Continent.ASIA), 
            new Country …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 java-stream

10
推荐指数
1
解决办法
255
查看次数

Java 8使用2个字段排序

根据一些条件,我从MongoDB读取数据并创建一个List<Document>带结果集.

List<Document> documentList = new ArrayList<Document>();
Run Code Online (Sandbox Code Playgroud)

样本记录看起来像:

documentList: [
    Document{
        { _id=5975ff00a213745b5e1a8ed9,
            u_id=,
            visblty = 1,
            c_id=5975ff00a213745b5e1a8ed8,                
            batchid=null,
            pdate=Tue Jul 11 17:52:25 IST 2017, 
            locale=en_US,
            subject = "Document2"
        }     },
    Document{
        { _id=597608aba213742554f537a6,
            u_id=,
            visblty = 1,
            c_id=597608aba213742554f537a3, 
            batchid=null,
            pdate=Fri Jul 28 01:26:22 IST 2017,
            locale=en_US,
            subject = "Document2"
        }    } 
]
Run Code Online (Sandbox Code Playgroud)

使用此documentList,我再次使用某些条件进行过滤,然后我需要根据某些条件(我将在请求中获取)对过滤器记录进行排序.

List<Document> outList = documentList.stream()
                .filter(d -> d.getInteger("visblty") == 1
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).after(afterDate)): true) 
                && (!StringUtils.isEmpty(req.pdate())? (d.getDate(CommonConstants.PDATE).before(beforeDate)): true)
                .sorted().skip(4).limit()
                .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

不确定如何排序(动态需要根据输入更改排序顺序,它看起来像" pdate by DESC"或" subject …

java sorting java-8 java-stream

10
推荐指数
3
解决办法
1万
查看次数

在filter()操作过滤掉所有内容后,Java流findAny()遇到空指针异常

我无法确定为什么在流上操作findAny()后抛出空指针异常filter().在这个特定的测试用例中,过滤器操作应该已经过滤掉所有内容,但没有结果findAny().

Optional<JsonNode> encryption = sseEncryptionList.stream()
                  .filter(n -> n.textValue().equals("AES256")) //Filters out everything
                  .findAny(); //Throws null pointer exception
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
at example.Main.lambda$main$0(Main.java:41)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1351)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)
at example.Main.main(Main.java:42)
Run Code Online (Sandbox Code Playgroud)

findAny()如果流不包含任何元素,这是否会抛出空指针异常?

编辑:解决可能过滤掉所有元素的过滤操作的优雅和功能方法是什么?

java java-8 java-stream

10
推荐指数
2
解决办法
5645
查看次数

Java Collectors.toMap的内存优化

我有一个将列表转换为地图的功能.调用此函数后,映射的大小不会更改.我正在尝试在以下两个实现之间做出决定:

Map<Long, Object> listToMap(List<Object> objs) {
        /* Implementation One: */

        Map<Long, Object> map = new HashMap<>(objs.size(), 1);
        for (Object obj : objs) {
            map.put(obj.getKey(), obj);
        }
        return map;

        /* Implementation Two: */

        return objs.stream().collect(Collectors.toMap(Object::getKey, obj -> obj));

    }
Run Code Online (Sandbox Code Playgroud)

在第一个实现中,我通过使用1的加载因子和列表的大小为所有元素分配了足够的内存.这确保不会执行调整大小操作.然后,我遍历列表并逐个添加元素.

在第二个实现中,我使用Java 8流来提高可读性.

我的问题是:第二个实现是否会涉及HashMap的多个调整大小,还是已经过优化以分配足够的内存?

java java-8 java-stream

10
推荐指数
2
解决办法
580
查看次数