是否可以创建一个适用于 Java 中不同 类 的通用方法?
Is it possible to create a generic method that is suitable for different classes in Java?
我有不同的 class 结构如下:
public class MyClass {
private String name;
private List<International> internationalList;
}
我想要的是有一个通用方法,它在国际列表中搜索并使用正确的语言设置本地化(例如:"en-us")。
示例:
public MyClass myMethod(String local, MyClass object){
for (International international : object.internationalList){
if(local.equals(international.language)){
object.name = international.translation
}
}
return myObject;
}
我不想为每个 class 重新编写此代码。是否可以创建适用于所有具有此结构的 classes 的通用方法?
这里有一个不用泛型解决问题的静态方法。
public static String lookUpName(String locale, String List<International> list) {
for (International international : list) {
if (local.equals(international.language) {
return international.translation;
}
}
return null; //or “” if that is preferred
}
这可能更像是评论,但我想添加足够的细节,不适合在评论中。
不清楚哪个 class 包含 myMethod(...)
,但该方法似乎支持来自包含数据的 MyClass
的国际化 外部 .这违反了告诉不要问的原则。
一种更面向对象的方法是 MyClass
知道如何进行自己的翻译。例如:
public class NameTranslator {
// constructor loads the List (or Map)
public String translate(String locale, String name) {
...
}
}
其中 MyClass
知道它的语言环境,并使用翻译器:
public class MyClass {
private final NameTranslator translator;
private final String locale;
private String name;
// constructor to set the translator and locale
public void setName(String name) {
String translatedName = translator.translate(locale, name);
if (translatedName != null) {
this.name = translatedName;
} else {
this.name = name; // or throw an IllegalStateException?
}
}
public String getName() {
return name;
}
}
所以译者不需要知道任何关于 MyClass
或任何其他 class.
此外,在搜索要翻译的项目时,Map 比 List 更快。
像
这样定义一个通用契约
public interface CommonInterface {
String getName();
void setName(String name);
List<International> getInternational();
}
让所有 classes 实现它。这是一个 class.
public class MyClass implements CommonInterface {
private String name;
private List<International> internationalList;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public List<International> getInternational() {
return internationalList; //Or create a defensive copy
}
}
您的常用方法如下所示
public <T extends CommonInterface> T myMethod(String local, T myObject) {
for (International international : myObject.getInternational()){
if(local.equals(international.language)) { //Better to avoid direct access and include getters in International class
myObject.setName(international.translation);
}
}
return myObject;
}
定义接口
您可以创建一个将由 MyClass
实现的接口
public interface LocationAware {
String getName();
void setName(String name);
List<International> getInternationals();
void setInternationals(List<International> internationals);
}
然后实现class喜欢
public static class MyClass implements LocationAware {
private String name;
private List<International> internationalList;
// getter and setters
}
您还可以使用 International
的接口并实现 class。
public interface International {
String getLanguage();
String getTranslation();
}
使用辅助方法
并且您可以在任何 class 中使用带有泛型的辅助方法,例如StaticClass
.
public static <T extends LocationAware> T changeLocationName(String local, T object) {
for (International international : object.getInternationals()) {
if(local.equals(international.getLanguage())) {
object.setName(international.getTranslation());
}
}
return object;
}
可以调用:
StaticClass.changeLocationName("en-us", myClass);
使用默认方法
由于您已经在使用一个接口,因此您可以拥有一个默认方法,它在没有辅助方法的情况下为您提供相同的功能。
public interface LocationAware {
default void changeLocationName(String local) {
for (International international : getInternationals()) {
if(local.equals(international.getLanguage())) {
setName(international.getTranslation());
}
}
}
String getName();
void setName(String name);
List<International> getInternationals();
void setInternationals(List<International> internationals);
}
并且只需使用 class 方法:
MyClass myClass = new Myclass(); // create and add name and internationals
myClass.changeLocationName("en-us"); // then change the location
在这里你可以决定如何处理local
的许多其他方式,例如,你可以存储值,当你使用getName()
时,return动态地使用当前名称,因此您不必每次都更改当前名称,(也可以使用地图来提高性能)。
public interface LocationAware {
default String getName() {
return getInternationals().get(getLocal());
}
void setName(String local);
String getLocal();
void setLocal(String local);
Map<String, International> getInternationals();
void setInternationals(Map<String, International> internationals);
}
注意:你应该处理位置不存在的情况
创建一个抽象 class,将方法 "MyMethod" 标记为静态,并在需要它的 classes 中以静态方式调用它。一个简单的解决方案。
我有不同的 class 结构如下:
public class MyClass {
private String name;
private List<International> internationalList;
}
我想要的是有一个通用方法,它在国际列表中搜索并使用正确的语言设置本地化(例如:"en-us")。
示例:
public MyClass myMethod(String local, MyClass object){
for (International international : object.internationalList){
if(local.equals(international.language)){
object.name = international.translation
}
}
return myObject;
}
我不想为每个 class 重新编写此代码。是否可以创建适用于所有具有此结构的 classes 的通用方法?
这里有一个不用泛型解决问题的静态方法。
public static String lookUpName(String locale, String List<International> list) {
for (International international : list) {
if (local.equals(international.language) {
return international.translation;
}
}
return null; //or “” if that is preferred
}
这可能更像是评论,但我想添加足够的细节,不适合在评论中。
不清楚哪个 class 包含 myMethod(...)
,但该方法似乎支持来自包含数据的 MyClass
的国际化 外部 .这违反了告诉不要问的原则。
一种更面向对象的方法是 MyClass
知道如何进行自己的翻译。例如:
public class NameTranslator {
// constructor loads the List (or Map)
public String translate(String locale, String name) {
...
}
}
其中 MyClass
知道它的语言环境,并使用翻译器:
public class MyClass {
private final NameTranslator translator;
private final String locale;
private String name;
// constructor to set the translator and locale
public void setName(String name) {
String translatedName = translator.translate(locale, name);
if (translatedName != null) {
this.name = translatedName;
} else {
this.name = name; // or throw an IllegalStateException?
}
}
public String getName() {
return name;
}
}
所以译者不需要知道任何关于 MyClass
或任何其他 class.
此外,在搜索要翻译的项目时,Map 比 List 更快。
像
这样定义一个通用契约public interface CommonInterface {
String getName();
void setName(String name);
List<International> getInternational();
}
让所有 classes 实现它。这是一个 class.
public class MyClass implements CommonInterface {
private String name;
private List<International> internationalList;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public List<International> getInternational() {
return internationalList; //Or create a defensive copy
}
}
您的常用方法如下所示
public <T extends CommonInterface> T myMethod(String local, T myObject) {
for (International international : myObject.getInternational()){
if(local.equals(international.language)) { //Better to avoid direct access and include getters in International class
myObject.setName(international.translation);
}
}
return myObject;
}
定义接口
您可以创建一个将由 MyClass
public interface LocationAware {
String getName();
void setName(String name);
List<International> getInternationals();
void setInternationals(List<International> internationals);
}
然后实现class喜欢
public static class MyClass implements LocationAware {
private String name;
private List<International> internationalList;
// getter and setters
}
您还可以使用 International
的接口并实现 class。
public interface International {
String getLanguage();
String getTranslation();
}
使用辅助方法
并且您可以在任何 class 中使用带有泛型的辅助方法,例如StaticClass
.
public static <T extends LocationAware> T changeLocationName(String local, T object) {
for (International international : object.getInternationals()) {
if(local.equals(international.getLanguage())) {
object.setName(international.getTranslation());
}
}
return object;
}
可以调用:
StaticClass.changeLocationName("en-us", myClass);
使用默认方法
由于您已经在使用一个接口,因此您可以拥有一个默认方法,它在没有辅助方法的情况下为您提供相同的功能。
public interface LocationAware {
default void changeLocationName(String local) {
for (International international : getInternationals()) {
if(local.equals(international.getLanguage())) {
setName(international.getTranslation());
}
}
}
String getName();
void setName(String name);
List<International> getInternationals();
void setInternationals(List<International> internationals);
}
并且只需使用 class 方法:
MyClass myClass = new Myclass(); // create and add name and internationals
myClass.changeLocationName("en-us"); // then change the location
在这里你可以决定如何处理local
的许多其他方式,例如,你可以存储值,当你使用getName()
时,return动态地使用当前名称,因此您不必每次都更改当前名称,(也可以使用地图来提高性能)。
public interface LocationAware {
default String getName() {
return getInternationals().get(getLocal());
}
void setName(String local);
String getLocal();
void setLocal(String local);
Map<String, International> getInternationals();
void setInternationals(Map<String, International> internationals);
}
注意:你应该处理位置不存在的情况
创建一个抽象 class,将方法 "MyMethod" 标记为静态,并在需要它的 classes 中以静态方式调用它。一个简单的解决方案。