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) 我正在使用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) 我有一个单词列表文本文件,我想从该文件中获取最小,最大和平均单词长度.
我有一个流方法:
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表达式)?
我试图弄清楚如何重写这个以使用流和过滤器来缩小我的标准并在必要时从地图中删除.
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) 我需要将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) 调用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()?
我有这个代码:
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) 根据一些条件,我从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 …
我无法确定为什么在流上操作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()如果流不包含任何元素,这是否会抛出空指针异常?
编辑:解决可能过滤掉所有元素的过滤操作的优雅和功能方法是什么?
我有一个将列表转换为地图的功能.调用此函数后,映射的大小不会更改.我正在尝试在以下两个实现之间做出决定:
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 ×10
java-stream ×10
java-8 ×9
lambda ×2
anagram ×1
collections ×1
file ×1
mapreduce ×1
sorting ×1