在许多其他语言中,例如.Haskell,很容易多次重复一个值或函数,例如.获取值为1的8个副本的列表:
take 8 (repeat 1)
Run Code Online (Sandbox Code Playgroud)
但我还没有在Java 8中找到它.在Java 8的JDK中是否有这样的功能?
或者相当于范围的东西
[1..8]
Run Code Online (Sandbox Code Playgroud)
它似乎是Java中冗长语句的明显替代品
for (int i = 1; i <= 8; i++) {
System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)
有类似的东西
Range.from(1, 8).forEach(i -> System.out.println(i))
Run Code Online (Sandbox Code Playgroud)
虽然这个特殊的例子实际上看起来并不简洁......但希望它更具可读性.
我有一个List<Person>.我需要List从一个属性获得Person.
例如,我有一个Person班级:
class Person
{
private String name;
private String birthDate;
public String getName() {
return name;
}
public String getBirthDate() {
return birthDate;
}
Person(String name) {
this.name = name;
}
}
List<Person> personList = new ArrayList<>();
personList.add(new Person("David"));
personList.add(new Person("Joe"));
personList.add(new Person("Michel"));
personList.add(new Person("Barak"));
Run Code Online (Sandbox Code Playgroud)
我想获得StreamAPI 的名称列表,如下所示:
List<String> names = personList.stream().somecode().collect(Collectors.toList());
names.stream().forEach(System.out::println);
#David
#Joe
#Michel
#Barak
Run Code Online (Sandbox Code Playgroud)
此代码不起作用:
public class Main
{
public static void main(String[] args)
{
List<Person> personList …Run Code Online (Sandbox Code Playgroud) 在Java 8之前我们拆分空字符串之类的
String[] tokens = "abc".split("");
Run Code Online (Sandbox Code Playgroud)
分裂机制会在标有的地方分开 |
|a|b|c|
Run Code Online (Sandbox Code Playgroud)
因为""每个字符前后都有空格.因此,它最初将生成此数组
["", "a", "b", "c", ""]
Run Code Online (Sandbox Code Playgroud)
然后将删除尾随的空字符串(因为我们没有明确地为limit参数提供负值),所以它最终会返回
["", "a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)
在Java 8中,拆分机制似乎已经发生了变化.现在我们用的时候
"abc".split("")
Run Code Online (Sandbox Code Playgroud)
我们将得到["a", "b", "c"]数组,而不是["", "a", "b", "c"]看起来像开始时的空字符串也被删除.但是这个理论失败了,例如
"abc".split("a")
Run Code Online (Sandbox Code Playgroud)
在start时返回带有空字符串的数组["", "bc"].
有人可以解释这里发生了什么,以及这些案例的拆分规则在Java 8中是如何变化的?
由于Java 8带有强大的lambda表达式,
我想写一个函数将一个List /数组的字符串转换为数组/整数列表,浮点数,双精度等.
在普通的Java中,它会如此简单
for(String str : strList){
intList.add(Integer.valueOf(str));
}
Run Code Online (Sandbox Code Playgroud)
但是如果将一个字符串数组转换为整数数组,我如何用lambda实现相同的效果.
在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM用于保存其类.在Java 8中,它被删除并被称为Metaspace的区域取代.
PermGen和Metaspace之间最重要的区别是什么?
我知道的唯一区别是java.lang.OutOfMemoryError: PermGen space不能再抛出并MaxPermSize忽略VM参数.
我刚刚在我们的生产环境中遇到了相当不愉快的经历 OutOfMemoryErrors: heapspace..
我将这个问题追溯到我ArrayList::new在函数中的使用.
要通过声明的构造函数(t -> new ArrayList<>())验证这实际上比正常创建更糟糕,我编写了以下小方法:
public class TestMain {
public static void main(String[] args) {
boolean newMethod = false;
Map<Integer,List<Integer>> map = new HashMap<>();
int index = 0;
while(true){
if (newMethod) {
map.computeIfAbsent(index, ArrayList::new).add(index);
} else {
map.computeIfAbsent(index, i->new ArrayList<>()).add(index);
}
if (index++ % 100 == 0) {
System.out.println("Reached index "+index);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行方法newMethod=true;将导致方法OutOfMemoryError在索引达到30k后失败.随着newMethod=false;程序不会失败,但一直冲击直到被杀(索引容易达到150万).
为什么在堆上ArrayList::new创建如此多的Object[]元素会导致OutOfMemoryError如此之快?
(顺便说一下 - 当集合类型出现时也会发生HashSet …
具体来说,我有TabPane,我想知道是否有特定ID的元素.
所以,我想用Java中的lambda表达式做到这一点:
boolean idExists = false;
String idToCheck = "someId";
for (Tab t : tabPane.getTabs()){
if(t.getId().equals(idToCheck)) {
idExists = true;
}
}
Run Code Online (Sandbox Code Playgroud) IntelliJ一直建议我用方法引用替换我的lambda表达式.
两者之间是否存在客观差异?
在我们的项目中,我们正在迁移到Java 8,我们正在测试它的新功能.
在我的项目中,我使用Guava谓词和函数来使用Collections2.transform和过滤和转换一些集合Collections2.filter.
在这次迁移中,我需要将例如guava代码更改为java 8更改.所以,我正在做的改变是这样的:
List<Integer> naturals = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10,11,12,13);
Function <Integer, Integer> duplicate = new Function<Integer, Integer>(){
@Override
public Integer apply(Integer n)
{
return n * 2;
}
};
Collection result = Collections2.transform(naturals, duplicate);
Run Code Online (Sandbox Code Playgroud)
至...
List<Integer> result2 = naturals.stream()
.map(n -> n * 2)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
使用guava我调试代码非常容易,因为我可以调试每个转换过程,但我关心的是如何调试例如.map(n -> n*2).
使用调试器我可以看到一些代码,如:
@Hidden
@DontInline
/** Interpretively invoke this form on the given arguments. */
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
return interpretWithArgumentsTracing(argumentValues);
checkInvocationCounter();
assert(arityCheck(argumentValues));
Object[] …Run Code Online (Sandbox Code Playgroud) 由于Java8最近已经发布,并且它的全新lambda表达式看起来非常酷,我想知道这是否意味着我们习以为常的Anonymous类的消亡.
我一直在研究这个问题,并找到了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如Collection的sort方法,它用于获取Comparator的Anonymous实例来执行排序:
Collections.sort(personList, new Comparator<Person>(){
public int compare(Person p1, Person p2){
return p1.firstName.compareTo(p2.firstName);
}
});
Run Code Online (Sandbox Code Playgroud)
现在可以使用Lambdas完成:
Collections.sort(personList, (Person p1, Person p2) -> p1.firstName.compareTo(p2.firstName));
Run Code Online (Sandbox Code Playgroud)
而且看起来非常简洁.所以我的问题是,有没有理由继续在Java8中使用这些类而不是Lambdas?
编辑
同样的问题,但在相反的方向,使用Lambdas而不是匿名类有什么好处,因为Lambdas只能用于单个方法接口,这个新功能只是在少数情况下使用的快捷方式还是真的有用?
java ×10
java-8 ×10
lambda ×4
collections ×2
arrays ×1
constructor ×1
debugging ×1
java-7 ×1
java-stream ×1
metaspace ×1
permgen ×1
regex ×1
split ×1