考虑以下代码:
public static void main(String[] args) {
Stream.iterate(1, i -> i + 1)
.flatMap(i -> Stream.of(i, i, i))
.peek(System.out::println)
.limit(4)
.forEach(i -> {});
}
Run Code Online (Sandbox Code Playgroud)
Java 8的输出:
1
1
1
2
2
2
Run Code Online (Sandbox Code Playgroud)
在Java 11中:
1
1
1
2
Run Code Online (Sandbox Code Playgroud)
这是Java 8中的错误或预期的行为,在11中进行了更改吗?
上面的代码只是演示不同行为的示例,但是更重要的含义是,以下代码在Java 11中显示1,2,3,但在Java 8中进入了无限循环:
Stream.iterate(0, i -> i + 10)
.flatMap(i -> Stream.iterate(i + 1, j -> j + 1))
.limit(3)
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud) 考虑这种方法(仅用于说明):
boolean isSmallNumber(String s) {
return (n in ["one", "two", "three", "four"]);
}
Run Code Online (Sandbox Code Playgroud)
当然,这不是Java,但它可能是您最喜欢的支持集合文字的替代语言,例如Groovy或Kotlin.表达式是简洁的,并且,就像字符串文字一样,允许编译器将集合文字放在某个静态存储区域(甚至可能是"intern()"它).
现在输入Java 9:
boolean isSmallNumber(String s) {
return Set.of("one", "two", "three", "four").contains(s);
}
Run Code Online (Sandbox Code Playgroud)
这也很简洁,但遗憾的是,每次调用它时,它都会在堆上分配一个新的Set,然后立即将其用于垃圾回收.
当然,您可以定义一个集合常量:
private static final Set<String> SMALL_NUMBERS = Set.of(...);
Run Code Online (Sandbox Code Playgroud)
但是,这个定义可能距离大类中的方法定义一千行,并且您可能无法想到一个好的描述性名称,而文字可能更清晰(在这个假设的情况下).
因此,如果我Set.of(...)在方法内部使用,那么每次调用方法时,JIT编译器是否会优化掉新对象的创建?
我想基于另一个数组(索引)的排序顺序迭代两个数组(A,B),在这种情况下是10,34,32,21.
String[] A: a, b, c, d
String[] B: e, f, g, h
int[] indexes: 10, 34, 32, 21
Run Code Online (Sandbox Code Playgroud)
在这里为坏榜样道歉.我更新了索引数组以清除混淆.
预期的输入和输出
输入是三个数组.我想使用索引数组的排序迭代A,B.即我想找到一种方法来使用顺序(a,d,c,b)迭代A并使用顺序(e,h,g,f)迭代B
我的方法:
我用一种我认为与另一种方法相同的解决方案解决了这个问题.但是,第二种方法不起作用.如果有人可以解释为什么它不起作用我会很感激,因为我认为这会让我更好地理解Collections.sort在java中的工作原理.
List<Integer> indexOrder = new ArrayList<>(indexes.length);
for (int i = 0; i < indexes.length; i++) {
indexOrder.add(i);
}
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[s]));
Run Code Online (Sandbox Code Playgroud)
受这个线程的启发,我创建了一个ArrayList(更喜欢AList not array),其值为(1,2,3 ... indices.length),然后使用带有ref的比较器对其进行排序.索引.上述代码按预期工作.
但是,如果我将最后一行末尾的索引[s]更改为索引[indexOrder.indexOf(s)].排序会产生错误的结果.如果ArrayList的索引与其值相同,为什么indexOf(s)给出的结果与s不同.
Collections.sort(indexOrder, Comparator.comparing((Integer s) -> indexes[indexOrder.indexOf(s)]));
Run Code Online (Sandbox Code Playgroud) 这个app问题询问和之间的区别,ate答案和cppreference都暗示唯一的区别是,这app意味着在每次写操作之前将写游标放在文件的末尾,而意味着ate将写游标放在文件的末尾仅在打开时才显示该文件。
我实际上看到的(在 VS 2012 中)是指定ate 丢弃现有文件的内容,而app不会(它将新内容附加到以前存在的内容)。换句话说,ate似乎是在暗示trunc。
以下语句将“Hello”附加到现有文件中:
ofstream("trace.log", ios_base::out|ios_base::app) << "Hello\n";
Run Code Online (Sandbox Code Playgroud)
但以下语句将文件的内容替换为“Hello”:
ofstream("trace.log", ios_base::out|ios_base::ate) << "Hello\n";
Run Code Online (Sandbox Code Playgroud)
VS 6.0 的 MSDN 文档暗示这种情况不应该发生(但这句话似乎在 Visual Studio 的更高版本中已被撤回):
ios::trunc:如果文件已经存在,则其内容将被丢弃。如果指定了 ios::out,并且未指定 ios::ate、ios::app 和 ios:in,则隐含此模式。
C:\Users\Malvolio>jshell
| Welcome to JShell -- Version 9.0.1
| For an introduction type: /help intro
jshell> assert(false)
jshell>
Run Code Online (Sandbox Code Playgroud)
当断言失败时,如何让Java Shell抛出AssertionError?
有什么区别
x as? String
Run Code Online (Sandbox Code Playgroud)
和
x as String?
Run Code Online (Sandbox Code Playgroud)
它们似乎都产生了一种String?类型.在科特林页面不回答对我来说.
更新:
澄清一下,我的问题是:
拥有一个as?操作符的目的是什么,因为对于任何对象x和任何类型T,表达式x as? T都可以(我认为)改写为x as T??
我有这个方法比较排序列表,并告诉你列表2中哪些项目从列表2中丢失,反之亦然,在O(N)时间:
fun <T : Comparable<T>> compareSortedLists(
list1: Iterable<T>,
list2: Iterable<T>,
onlyInList1: MutableCollection<T>,
onlyInList2: MutableCollection<T>) {
val it1 = PeekingIterator(list1.iterator())
val it2 = PeekingIterator(list2.iterator())
while (it1.hasNext() && it2.hasNext()) {
val comp = it1.peek().compareTo(it2.peek())
if (comp < 0) // <-- ERROR: type inference failure
onlyInList1.add(it1.next())
else if (comp > 0)
onlyInList2.add(it2.next())
else {
it1.next()
it2.next() // <---- Error: type mismatch
}
}
it1.forEachRemaining { onlyInList1.add(it) }
it2.forEachRemaining { onlyInList2.add(it) }
}
Run Code Online (Sandbox Code Playgroud)
IntelliJ IDEA 2018.1.4中的Kotlin编译器(1.2.41)给出了编译时错误(如上所示).错误消息说:
Type mismatch.
Required: Comparable<Boolean>!
Found: T!
Run Code Online (Sandbox Code Playgroud)
但我并不打算if …
当我在JShell(9.0.1)中输入表达式时,它返回:
$22 -> <value>
Run Code Online (Sandbox Code Playgroud)
22的来源是什么,1美元到21美元之间发生了什么?(它们是未定义的。)
我似乎隐约记得(当我从Java 9.0开始时)变量以$ 1开头,这更有意义。现在,从9.0.1起,它们全部以22美元开始。为什么?
我有一个问题,我想知道是否有使用 Streams 的解决方案。
想象一下你有一个有序的对象流;让我们假设一个整数流。
Stream<Integer> stream = Stream.of(2,20,18,17,4,11,13,6,3,19,4,10,13....)
Run Code Online (Sandbox Code Playgroud)
现在我想过滤一个值与该值之前的前一个数字之差大于n的所有值。
stream.filter(magicalVoodoo(5))
// 2, 20, 4, 11, 3, 19, 4, 10 ...
Run Code Online (Sandbox Code Playgroud)
我有可能这样做吗?
我知道传统的import声明是针对类的,而import static声明是针对静态成员的。但是静态嵌套类应该使用什么?
考虑:
public class MyUtilityClass {
public static class SomeNestedClass {
//...
}
public static class AnotherNestedClass {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
与用法:
import MyUtilityClass.AnotherNestedClass;
import static MyUtilityClass.SomeNestedClass;
public class Main {
public static void main(String[] args) {
SomeNestedClass a = new SomeNestedClass();
AnotherNestedClass b = new AnotherNestedClass();
}
}
Run Code Online (Sandbox Code Playgroud)
您会看到,importandimport static语句都可以使用。但哪一种更正确、更典型,或者被大多数编码指南推荐呢?
java ×7
java-9 ×3
java-stream ×2
kotlin ×2
algorithm ×1
c++ ×1
collections ×1
comparator ×1
flatmap ×1
fstream ×1
java-11 ×1
java-8 ×1
jshell ×1
lambda ×1
sorting ×1