谈论Streams,当我执行这段代码时
public class Main {
public static void main(String[] args) {
Stream.of(1,2,3,4,5,6,7,8,9)
.peek(x->System.out.print("\nA"+x))
.limit(3)
.peek(x->System.out.print("B"+x))
.forEach(x->System.out.print("C"+x));
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了这个输出
A1B1C1
A2B2C2
A3B3C3
Run Code Online (Sandbox Code Playgroud)
因为将我的流限制为前三个组件会强制执行动作A,B和C三次.
尝试使用skip()方法对最后三个元素执行类似的计算,显示了不同的行为:这
public class Main {
public static void main(String[] args) {
Stream.of(1,2,3,4,5,6,7,8,9)
.peek(x->System.out.print("\nA"+x))
.skip(6)
.peek(x->System.out.print("B"+x))
.forEach(x->System.out.print("C"+x));
}
}
Run Code Online (Sandbox Code Playgroud)
输出这个
A1
A2
A3
A4
A5
A6
A7B7C7
A8B8C8
A9B9C9
Run Code Online (Sandbox Code Playgroud)
在这种情况下,为什么执行A1到A6的操作?它必须与limit是一个短路状态中间操作这一事实有关,而skip不是,但我不明白这个属性的实际含义.是不是"在跳过之前的所有动作都被执行而不是每个人都在限制之前"?
我对内部类和lambda表达有些困惑,我试着问一个问题,然后又出现了另一个疑问,并且可能更好地发布另一个问题,而不是评论前一个问题.
直截了当:我知道(谢谢Jon)这样的事情无法编译
public class Main {
public static void main(String[] args) {
One one = new One();
F f = new F(){ //1
public void foo(){one.bar();} //compilation error
};
one = new One();
}
}
class One { void bar() {} }
interface F { void foo(); }
Run Code Online (Sandbox Code Playgroud)
由于Java如何管理闭包,因为one不是[有效]最终等等.
但是,这怎么允许的呢?
public class Main {
public static void main(String[] args) {
One one = new One();
F f = one::bar; //2
one = …Run Code Online (Sandbox Code Playgroud) 试图编译这段代码
public class Main {
public static void main(String args[]) {
new Main();
}
{ System.out.println(x); } //Error here
int x=1;
}
Run Code Online (Sandbox Code Playgroud)
产生cannot reference a field before it is defined错误.但是如果我将初始化器行更改为
{ System.out.println(this.x); }
Run Code Online (Sandbox Code Playgroud)
它就像一个魅力,打印默认的int值0.
这对我来说有点混乱,为什么会this有所不同呢?在这种情况下,它不应该是多余的吗?任何人都可以解释我幕后发生的事情,以明确它是如何工作的吗?
PS:我知道通过x在初始化程序之前声明它也可以使它工作.
假设我们有这个流
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j");
Run Code Online (Sandbox Code Playgroud)
我想在地图中保存相邻字符串的对,其中第一个以"错误"开头.
我想到的是这样的
Map<String, String> map = new HashMap<>();
Stream.of("a", "b", "err1", "c", "d", "err2", "e", "f", "g", "h", "err3", "i", "j")
.reduce((acc, next) -> {
if (acc.startsWith("err"))
map.put(acc,next);
if (next.startsWith("err"))
return next;
else
return "";
});
Run Code Online (Sandbox Code Playgroud)
但出于两个主要原因,我并不完全满意
reduce功能.在Stream API中,每个函数都有其明确,明确的目的:max应该计算最大值,filter应该根据条件进行过滤,reduce应该产生递增累积值等等.在这里我使用reduce因为(据我所知)它是唯一的功能,它可以让你比较几个值,你可以,不知何故,回到类似"当前值"和"下一个值"的概念.
有更简单的方法吗?是否允许您为每次迭代考虑多个值来迭代流?
我正在考虑的是一些机制,给定当前元素,允许您为每次迭代定义要考虑的"元素窗口".
就像是
<R> Stream<R> mapMoreThanOne(
int elementsBeforeCurrent,
int elementsAfterCurrent,
Function<List<? super T>, ? …Run Code Online (Sandbox Code Playgroud) 我只是注意到JDK8为Integer类引入了这个方法:
/**
* Adds two integers together as per the + operator.
*
* @param a the first operand
* @param b the second operand
* @return the sum of {@code a} and {@code b}
* @see java.util.function.BinaryOperator
* @since 1.8
*/
public static int sum(int a, int b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
这种方法有什么意义?为什么我应该调用此方法而不是使用+运算符?我能想到的唯一可能性是,例如,当混合字符串和整数时,+操作符会改变含义,因此
System.out.println("1"+2+3); // prints 123
System.out.println("1"+Integer.sum(2,3)); // prints 15
Run Code Online (Sandbox Code Playgroud)
但无论如何,使用括号会起作用
System.out.println("1"+(2+3)); // prints 15
Run Code Online (Sandbox Code Playgroud) 我设法解析String一个LocalDate对象:
DateTimeFormatter f1=DateTimeFormatter.ofPattern("dd MM yyyy");
LocalDate d=LocalDate.parse("26 08 1984",f1);
System.out.println(d); //prints "1984-08-26"
Run Code Online (Sandbox Code Playgroud)
但我不能这样做LocalTime.这段代码:
DateTimeFormatter f2=DateTimeFormatter.ofPattern("hh mm");
LocalTime t=LocalTime.parse("11 08",f2); //exception here
System.out.println(t);
Run Code Online (Sandbox Code Playgroud)
抛出一个DateTimeParseException:
Exception in thread "main" java.time.format.DateTimeParseException: Text '11 08' could not be parsed: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=8, HourOfAmPm=11},ISO of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(Unknown Source)
at java.time.format.DateTimeFormatter.parse(Unknown Source)
at java.time.LocalTime.parse(Unknown Source)
at com.mui.cert.Main.<init>(Main.java:21)
at com.mui.cert.Main.main(Main.java:12)
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=8, HourOfAmPm=11},ISO of type …Run Code Online (Sandbox Code Playgroud) 我确实阅读了许多讨论内部类的主题,我的印象是内部类可以访问封闭类的变量和方法.在下面我有一个外部类和一个内部类,在测试类中我创建了一个外部类的实例,然后从中创建了一个内部类的实例.但是我无法通过内部类引用访问String变量a.救命?
public class OuterClass {
String a = "A";
String b = "B";
String c = "C";
class InnerClass {
int x;
}
public static class StaticInnerClass {
int x;
}
public String stringConCat() {
return a + b + c;
}
}
public class TestStatic {
public static void main(String args[]) {
OuterClass.StaticInnerClass staticClass = new OuterClass.StaticInnerClass();
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
System.out.println(inner.a);// error here, why can't i access the string
// variable a …Run Code Online (Sandbox Code Playgroud) 阅读Instant类的源代码,我碰到了这个方法
/**
* Defend against malicious streams.
*
* @param s the stream to read
* @throws InvalidObjectException always
*/
private void readObject(ObjectInputStream s) throws InvalidObjectException {
throw new InvalidObjectException("Deserialization via serialization delegate");
}
Run Code Online (Sandbox Code Playgroud)
描述让我很好奇.什么是"恶意流"?这种方法如何防御呢?
我正在阅读课程的APIZoneId.它声明有三种ID:
具有某种形式前缀的偏移式ID.例子:
ZoneId.of("GMT+2");
ZoneId.of("UTC");
ZoneId.of("UT+01:00");
Run Code Online (Sandbox Code Playgroud)区域为主.例子:
ZoneId.of("Asia/Aden");
ZoneId.of("Etc/GMT+9");
ZoneId.of("Asia/Aqtau");
Run Code Online (Sandbox Code Playgroud)但是第一种正确的语法是什么?文档说
[来自ZoneOffset的ID]由'Z'和以'+'或' - '开头的ID组成.
什么是String和ZoneOffset对象的组合我应该用来创建ZoneId第一种?
有人可以帮助我理解为什么这段代码的行为如评论中所述
// 1) compiles
List<Integer> l = Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList<Integer>::addAll);
/*
* 2) does not compile
*
* Exception in thread "main" java.lang.Error: Unresolved compilation problems:
* Type mismatch: cannot convert from Object to <unknown>
* The type ArrayList does not define add(Object, Integer) that is applicable here
* The type ArrayList does not define addAll(Object, Object) that is applicable here
*/
Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
// 3) compiles
Stream.of(1, 2, 3).collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);
/*
* 4) …Run Code Online (Sandbox Code Playgroud)