Java 8中是否存在方法的align=right
关键字的任何类似物?
假设我有一个功能界面:
text-align:right
一个包含3种静态方法的库“实现”这个功能界面:
implements
将来我希望能够互换地使用这3种方法的任何引用作为参数。例如:
@FunctionalInterface
interface LongHasher {
int hash(long x);
}
如何在编译时确保class LongHashes {
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
static int randomHash(long x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
,static LongHashMap createHashMap(LongHasher hasher) { ... }
...
public static void main(String[] args) {
LongHashMap map = createHashMap(LongHashes::randomHash);
...
}
和LongHashes::xorHash
与LongHashes::continuingHash
具有相同的签名?
答案 0 :(得分:9)
过去我也曾希望这样做,但不,你不能这样做。但是你知道。在Java 8之前有Java。请改为:
enum LongHashes implements LongHasher {
XOR {
@Override
public int hash(long x) { ... }
},
CONTINUING {
@Override
public int hash(long x) { ... }
},
RANDOM {
@Override
public int hash(long x) { ... }
}
}
然后:
public static void main(String[] args) {
LongHashMap map = createHashMap(LongHashes.RANDOM);
...
}
答案 1 :(得分:8)
你没有要求的语法结构。但是,您可以在显式将方法引用分配给接口时创建静态常量:
class LongHashes {
private static final LongHasher XOR_HASH = LongHashes::xorHash;
private static final LongHasher CONTINUING_HASH = LongHashes::continuingHash;
private static final LongHasher RANDOM_HASH = LongHashes::randomHash;
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
static int randomHash(long x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
这样,如果方法签名或接口以不兼容的方式更改,则编译将中断。如果您愿意,可以声明它们public
并使用而不是方法引用。
如果你担心这些静态lambda将在运行时挂在内存中,你可以将这个声明移动到单独的类(例如,嵌套),它编译但从不加载。
答案 2 :(得分:3)
您可以声明函数对象,而不是方法。
class LongHashes {
static final LongHasher xorHash = x -> {
return (int)(x ^ (x >>> 32));
};
... etc
LongHashMap map = createHashMap(LongHashes.randomHash);
答案 3 :(得分:1)
一种方法是直接从LongHasher
类返回LongHashes
:
class LongHashes {
private static int xorHashImpl(long x) {
return (int)(x ^ (x >>> 32));
}
static LongHasher xorHash() {
return LongHashes::xorHashImpl;
}
}
但是这会为你的LongHashes
类添加一些代码,并将其与LongHasher
接口联系起来,这可能是不可取的(尽管这基本上就是你所要求的)。
答案 4 :(得分:1)
或者只创建3个实现LongHasher的类。当您需要LongHasher时,获取或创建一个实例并传递它:
LongHasher longHasher = ... // new RandomLongHasher(), factory, .......
LongHashMap map = createHashMap(longHasher);
在此处将函数编写为静态方法:
我们并没有被迫在任何地方使用lambdas。
答案 5 :(得分:0)
虽然我发现Tagir的答案很好,但是当一个人创建一个新的哈希时,很容易忘记添加私有常量。
像往常一样,在处理潜在的重构问题时,我认为测试就是答案:
public class LongHashesTest {
@Test
public void xorHash() {
LongHasher xorHash = LongHashes::xorHash;
assertEquals(1768181579, xorHash.hash(34312465426524234l));
}
@Test
public void continuingHash() {
LongHasher continuingHash = LongHashes::continuingHash;
assertEquals(1529080340, continuingHash.hash(74543524355l));
}
@Test
public void randomHash() {
LongHasher randomHash = LongHashes::randomHash;
assertEquals(-1100764221, randomHash.hash(4343245345432154353l));
}
}