Java 和哈希码中的通用类型
Generic Types in Java and Hash Codes
虽然我知道这不是创建哈希码的最有效方法,但我正在努力通过将数据转换为整数来制作哈希码,这将是它们的哈希码。我正在处理只有 32 位或更少的数据类型(因此只有字节、整数、字符、短整型和浮点型)。在创建程序时,我 运行 遇到了一个必须由泛型引起的问题。我有一个 class,它只接受我上面讨论的数据类型,方法是在 if 中使用 java 中的 instanceof 关键字:
public class HashCode<T>
{
public static void main(String[]args)
{
codeAsInt(2);
codeAsInt('C');
codeAsInt("name");
}
public int codeAsInt(T value)
{
if(value instanceof Integer || value instanceof Character || value instanceof Short || value instanceof Float || value instanceof Byte)
{
int hashcode = (int)value;
return hashcode;
}
else
{
//you cannot use this method return -1
return -1;
}
}
这样做会导致错误,因为我无法将 "value" 中的任何一种类型转换为 T。无论如何我可以将不同的数据类型传递给使用泛型的方法吗?我知道我可以使用方法重载(创建接受不同数据类型的不同方法)来解决这个问题,但据我所知,方法重载与做不同事情的方法一起使用,对于我的方法,它做同样的事情(将数据转换为整数).我也知道我可以创建一个单独的 class 来执行此操作,但我认为这对于这样一个简单的任务来说效率很低。
编译时出错:
error: incompatible types: int cannot be converted to T
codeAsInt(2);
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: char cannot be converted to T
codeAsInt('C');
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: String cannot be converted to T
codeAsInt("name");
^
where T is a type-variable:
T extends Object declared in class HashCodes
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
3 errors
Tool completed with exit code 1
任何帮助以及任何比我正在使用的方法更好的方法都将不胜感激。
我想你说的是 serialization
错误信息
我猜你得到的错误来自于从静态上下文调用通用非静态方法。要使您的代码编译,但不能直接工作 ;),您应该将 main
方法中的调用更改为如下内容:
new HashCode<Integer>().codeAsInt(2);
new HashCode<Character>().codeAsInt('C');
new HashCode<String>().codeAsInt("name");
因此在您的情况下,需要在创建对象时实例化 class 并指定 T
的类型。您似乎想让编译器通过参数推断类型。
Here Oracle 给出了有关 java 类型推断机制的提示,您可以按如下方式使用 class。
HashCode<Integer> i = new HashCode<>().codeAsInt(2);
HashCode<Character> c = new HashCode<>().codeAsInt('C');
HashCode<String> s = new HashCode<>().codeAsInt("name");
i.codeAsInt(2);
c.codeAsInt('C');
s.codeAsInt("name");
因此您可以在实例化时省略类型信息,但不能在声明中省略。我不是 100% 确定是否可以使用 java 1.8 的类型推断以更简洁的方式编写它。
可能的解决方案
自 java 1.7 及更早版本以来,可以使用 java 的类型文字来实现类似的功能。但是随后您必须始终将该文字显式传递给该方法。您的整个 class 没有明确要求是通用的,如果您想 select 在每个单独的方法调用上使用类型,那么将单个方法设为通用就足够了。
public class SomeClass {
public static <T> int codeAsInt(Class<T> type, T value) {
// here you can use the type object
if(type.isInstance(value)) {
// ...
}
public static void main(String... args) {
codeAsInt(Integer.class, 2);
codeAsInt(Character.class, 'C');
codeAsInt(String.class, "name");
}
}
如果对象的类型为 T
,则 Class
type gives you an object for the type T
at runtime, because that isn't usually available anymore after compilation. With the type
object you can do casting to T
at runtime. There is some cast
method, which takes an Object
and returns a T
. Furthermore you can check with the isInstance
方法。然而,选择所描述的方法会使类型检查过时,因为如果您不小心将某些内容传递给非 T
.
类型的方法,编译器会通知您
我仍然不确定您到底在寻找什么,但我希望这对您有所帮助。如果您只想将任何类型的对象动态转换为 T
,只需直接使用类型字面量转换方法即可。
盲写,不保证拼写错误或编译错误;)
这里是 class 使用反射,你必须处理抛出的异常并管理它们:
public class Test {
public static void main(String[] args) { // Manage command line argument
try
{
System.out.println(getHashCode("java.lang.String", "10")); // For simplicity
}
catch(Exception e)
{
System.err.println("There's a problem with this test ! Here is the details :\n"+e.getMessage());
}
}
public static int getHashCode(String className, String value) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<?> clazz = Class.forName(className);
Constructor<?> c = clazz.getConstructor(String.class);
Object o = c.newInstance(value);
return o.hashCode();
}
}
虽然我知道这不是创建哈希码的最有效方法,但我正在努力通过将数据转换为整数来制作哈希码,这将是它们的哈希码。我正在处理只有 32 位或更少的数据类型(因此只有字节、整数、字符、短整型和浮点型)。在创建程序时,我 运行 遇到了一个必须由泛型引起的问题。我有一个 class,它只接受我上面讨论的数据类型,方法是在 if 中使用 java 中的 instanceof 关键字:
public class HashCode<T>
{
public static void main(String[]args)
{
codeAsInt(2);
codeAsInt('C');
codeAsInt("name");
}
public int codeAsInt(T value)
{
if(value instanceof Integer || value instanceof Character || value instanceof Short || value instanceof Float || value instanceof Byte)
{
int hashcode = (int)value;
return hashcode;
}
else
{
//you cannot use this method return -1
return -1;
}
}
这样做会导致错误,因为我无法将 "value" 中的任何一种类型转换为 T。无论如何我可以将不同的数据类型传递给使用泛型的方法吗?我知道我可以使用方法重载(创建接受不同数据类型的不同方法)来解决这个问题,但据我所知,方法重载与做不同事情的方法一起使用,对于我的方法,它做同样的事情(将数据转换为整数).我也知道我可以创建一个单独的 class 来执行此操作,但我认为这对于这样一个简单的任务来说效率很低。
编译时出错:
error: incompatible types: int cannot be converted to T
codeAsInt(2);
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: char cannot be converted to T
codeAsInt('C');
^
where T is a type-variable:
T extends Object declared in class HashCodes
error: incompatible types: String cannot be converted to T
codeAsInt("name");
^
where T is a type-variable:
T extends Object declared in class HashCodes
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
3 errors
Tool completed with exit code 1
任何帮助以及任何比我正在使用的方法更好的方法都将不胜感激。
我想你说的是 serialization
错误信息
我猜你得到的错误来自于从静态上下文调用通用非静态方法。要使您的代码编译,但不能直接工作 ;),您应该将 main
方法中的调用更改为如下内容:
new HashCode<Integer>().codeAsInt(2);
new HashCode<Character>().codeAsInt('C');
new HashCode<String>().codeAsInt("name");
因此在您的情况下,需要在创建对象时实例化 class 并指定 T
的类型。您似乎想让编译器通过参数推断类型。
Here Oracle 给出了有关 java 类型推断机制的提示,您可以按如下方式使用 class。
HashCode<Integer> i = new HashCode<>().codeAsInt(2);
HashCode<Character> c = new HashCode<>().codeAsInt('C');
HashCode<String> s = new HashCode<>().codeAsInt("name");
i.codeAsInt(2);
c.codeAsInt('C');
s.codeAsInt("name");
因此您可以在实例化时省略类型信息,但不能在声明中省略。我不是 100% 确定是否可以使用 java 1.8 的类型推断以更简洁的方式编写它。
可能的解决方案
自 java 1.7 及更早版本以来,可以使用 java 的类型文字来实现类似的功能。但是随后您必须始终将该文字显式传递给该方法。您的整个 class 没有明确要求是通用的,如果您想 select 在每个单独的方法调用上使用类型,那么将单个方法设为通用就足够了。
public class SomeClass {
public static <T> int codeAsInt(Class<T> type, T value) {
// here you can use the type object
if(type.isInstance(value)) {
// ...
}
public static void main(String... args) {
codeAsInt(Integer.class, 2);
codeAsInt(Character.class, 'C');
codeAsInt(String.class, "name");
}
}
如果对象的类型为 T
,则 Class
type gives you an object for the type T
at runtime, because that isn't usually available anymore after compilation. With the type
object you can do casting to T
at runtime. There is some cast
method, which takes an Object
and returns a T
. Furthermore you can check with the isInstance
方法。然而,选择所描述的方法会使类型检查过时,因为如果您不小心将某些内容传递给非 T
.
我仍然不确定您到底在寻找什么,但我希望这对您有所帮助。如果您只想将任何类型的对象动态转换为 T
,只需直接使用类型字面量转换方法即可。
盲写,不保证拼写错误或编译错误;)
这里是 class 使用反射,你必须处理抛出的异常并管理它们:
public class Test {
public static void main(String[] args) { // Manage command line argument
try
{
System.out.println(getHashCode("java.lang.String", "10")); // For simplicity
}
catch(Exception e)
{
System.err.println("There's a problem with this test ! Here is the details :\n"+e.getMessage());
}
}
public static int getHashCode(String className, String value) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<?> clazz = Class.forName(className);
Constructor<?> c = clazz.getConstructor(String.class);
Object o = c.newInstance(value);
return o.hashCode();
}
}