我有一个矩阵类,我想在这个类中创建一个名为 map 的函数,它看起来像这样
public void map(T fn) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
该函数背后的想法是作为参数 fn,它可以是任何方法并将此方法应用于矩阵中的每个数字。
它背后的想法是针对神经网络上的编码训练视频,但我尝试在 Java 中对其进行操作,但没有奏效。我搜索 lambda 表达式,但是当我使用它时,它只让我传递像 Math.cos(arg ) 里面有一个参数。但我希望它在没有任何参数的情况下传递当前函数看起来像这样
interface lambda<T> {
double foo(T fn);
}
public void map(T fn) {
for(int i = 0 ; i< this.getRow() ; i++) {
for(int j = 0 ; j< this.getCol(); j++) {
int a = i;
int b = j;
lambda mycode = (T) -> setData(matrix[a][b], fn);
matrix[i][j] = mycode.foo(fn);
}
}
}
private double setData(double data, T fn) { …Run Code Online (Sandbox Code Playgroud) 作为我正在编写的编程语言的编译器的一部分,我在字节码中遇到了通用签名,我试图解析并转换为AST.解析算法大多数都有效,但似乎有一种特殊情况,这些签名的格式有点奇怪.以下是一些这样的情况:
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;)V
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;II)V
java.lang.Class#getAnnotation: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
java.lang.Class#getAnnotationsByType: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)[TA;
java.lang.Class#getDeclaredAnnotation: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
java.lang.Class#getDeclaredAnnotationsByType: <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)[TA;
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;)V
java.util.Arrays#parallelSort: <T::Ljava/lang/Comparable<-TT;>;>([TT;II)V
java.util.Collections#sort: <T::Ljava/lang/Comparable<-TT;>;>(Ljava/util/List<TT;>;)V
Run Code Online (Sandbox Code Playgroud)
在这些类中的所有方法中,这些是唯一具有::签名的方法.我的问题是这个令牌的作用以及它存在的原因.
编辑
我知道Java语言中的::运算符,但这是字节码级别的内容.
假设我有一个Gizmo带有构造函数的类,它接受一个String.假设我想将a转换List<String>为a List<Gizmo>.
我可能会写:
List<String> strings = new ArrayList<>();
List<Gizmo> gizmos = strings
.stream()
.map(str -> new Gizmo(str))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
现在,问题是IntelliJ告诉我我可以用方法引用替换lambda.事实是,我很确定方法引用不能参数.
在Java 8之前,我的观察是,引用成员方法的事实标准是使用#符号(例如Object#toString()).然后是Java 8,它选择了::运算符进行方法引用,看似没有理由.
对于为何::特别选择了原因,是否有官方解释或理由?
在流的排序方法中使用Comparator::reverseOrder和之间的区别是什么Comparator.reverseOrder().
Stream<String> streamText = Stream.of("over the river", "through the woods", "to grandmother's house we go");
Run Code Online (Sandbox Code Playgroud)
这有效:
streamText.filter(n -> n.startsWith("t"))
.sorted(Comparator.reverseOrder())
.findFirst().ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud)
但这不编译:
streamText.filter(n -> n.startsWith("t"))
.sorted(Comparator::reverseOrder)
.findFirst().ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud) 我正在编写一个涉及多线程工作池的Java程序Process.该类的每个实例都Process需要能够生成一个额外的线程来完成一些工作.但是线程应该由实例本身和其他人产生.不幸的Runnable.run是'公开'所以如果不做一些技巧我就无法真正强制执行.
这是我计划使用的技巧:
Runnable中Process码:
class Process implements Runnable {
private boolean threadkey = false;
public void run() {
synchronized(threadkey) {
// is someone wrongly calling 'run'?
if(!threadkey)
return;
/* switch off threadkey to make sure
it cannot be called meaningfully again */
threadkey = false;
}
/* continue processing
*
*/
return;
}
Run Code Online (Sandbox Code Playgroud)
当然,现在我需要做的就是run合法地在打电话之前打开'threadkey'(私有).
优雅?或不?或者,还有更好的方法?或者我应该不打扰执行此并写一个简洁的小评论解释不要打电话'跑'?
人们甚至会在需要做"跑步"的班级内打电话给"跑"吗?
我用简单List的示例值写了,我希望流从Stream返回最大值.我知道max()功能需要,Comparator但事实证明,我也可以通过Integer::max(任何人都可以解释我的,为什么?).
此外,程序打印出奇怪的结果,我在"内部"检查它看起来没问题,但在我得到最终结果后 - 它们不准确.
例:
@Test
public void testHowIntegerMaxWorksInStream() {
List<Integer> list = Arrays.asList(5,3,8);
Optional<Integer> op = list.stream().max((a, b) -> {
System.out.println("Input arguments a=" + a + ", b=" + b);
int max = Integer.max(a, b);
System.out.println("Returning max(a,b)=" + max);
return max;
});
System.out.println("Optional result=" + op.get());
}
Run Code Online (Sandbox Code Playgroud)
输出:
Input arguments a=5, b=3
Returning max(a,b)=5
Input arguments a=5, b=8
Returning max(a,b)=8 // OK, Integer::max got 8.. but then ...
Optional result=5 // …Run Code Online (Sandbox Code Playgroud) 我最近把手放在Java 8上并尝试使用方法参考.我正在尝试不同类型的方法引用,并陷入"引用特定类型的任意对象的实例方法"类型中.
String[] arr = {"First", "Second", "Third", "Fourth"};
Arrays.sort(arr, String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
这非常有效.但是当我尝试通过其类型引用用户定义类的方法时:
Demo2[] arr = {a, b};
Arrays.sort(arr, Demo2::compare);
Run Code Online (Sandbox Code Playgroud)
这将编译时错误显示为"无法从静态上下文引用非静态方法".
这是Demo2类:
public class Demo2 implements Comparator<Demo2> {
Integer i;
Demo2(Integer i1){
i = i1;
}
public Integer getI() {
return i;
}
@Override
public int compare(Demo2 o1, Demo2 o2) {
return o1.getI().compareTo(o2.getI());
}
}
Run Code Online (Sandbox Code Playgroud) 这个问题已被提出,但答案似乎不完整.以下上下文中的第一个冒号是什么意思?
import hudson.model.SCMS;
(...)
SCMS: for (SCM scm : scmTriggerItem.getSCMs()) {
(...)
Run Code Online (Sandbox Code Playgroud)
此外,冒号在Java 8中有一些新的用途.
这个问题(最初在两年前提出过)与循环java代码不同,因为它更广泛.虽然原始问题的答案没有提到使用冒号作为标签,这在"java-code-loop-code"中得到了回答,但后一个问题并没有要求在for循环中使用冒号也没有在Java 8中.
正如biziclop的答案所示,Java语法中的冒号用法容易被遗忘,而在其他两个问题中则没有提及.
Java有::运营商吗?请不要关闭这个问题,我确实搜索了文档,我确定它没有,但我想完全确定.
也就是说,在Java中可以有类似MyClass::x或类似的东西.
使用Apache公共数学库,我得到一个原始的双数组.
RealMatrix pInverse = new LUDecomposition(p).getSolver().getInverse();
double[][] temp = pInverse.getData();
Run Code Online (Sandbox Code Playgroud)
我需要将temp转换为a Double[][]
Double[][] inverse = new Double[][]temp;
Run Code Online (Sandbox Code Playgroud) 我知道它们有相同的效果,但为什么会Integer::intValue出错?
public class ResistorColorDuo {
Map<String, Integer> colValueMap;
public ResistorColorDuo(Map<String, Integer> colValueMap) {
colValueMap.put("Black", 0);
colValueMap.put("Brown", 1);
colValueMap.put("Red", 2);
colValueMap.put("Orange", 3);
colValueMap.put("Yellow", 4);
colValueMap.put("Green", 5);
colValueMap.put("Blue", 6);
colValueMap.put("Violet", 7);
colValueMap.put("Grey", 8);
colValueMap.put("White", 9);
this.colValueMap = colValueMap;
}
public int getResistorValue(String... colors) {
return Arrays.stream(colors).map(i -> colValueMap.get(i) *
Math.pow(10, colors.length - (Arrays.asList(colors).indexOf(i) + 1)))
.mapToInt(Integer::intValue) // Here occurs an exception
.sum();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码产生了一个错误:
不能从静态上下文中引用非静态方法
虽然它像这样工作得很好:
public int getResistorValue(String... colors) {
return Arrays.stream(colors).map(i -> colValueMap.get(i) *
Math.pow(10, colors.length - …Run Code Online (Sandbox Code Playgroud) List<Animal> animals = this.service.findAll();
animals = animals.stream().sorted(Comparator.comparing(Animal::getName)).collect(Collectors.toList());
//working
Run Code Online (Sandbox Code Playgroud)
而
List<Animal> animals = this.service.findAll();
animals = animals.stream().sorted(Comparator.comparing(Animal.getName()).collect(Collectors.toList());
//Not working..
Run Code Online (Sandbox Code Playgroud)
任何人都可以告诉我为什么我不能使用比较器比较没有方法参考?
java ×13
java-8 ×7
lambda ×3
comparator ×2
java-stream ×2
arrays ×1
double ×1
generics ×1
jvm ×1
jvm-bytecode ×1
operators ×1
sorting ×1
stream ×1
syntax ×1