如何使用泛型来简化我的编辑方法
How to use Generics to simplify my Edit Method
在我的程序中,我试图创建一个方法来编辑 BaseContact 中的任何 属性。 BaseContact 是在 PersonContact 和 BusinessContact class 中扩展的抽象 class。我想创建一个编辑方法,询问用户 属性 他们想要编辑什么,向他们显示旧值,然后更新为他们想要的新值。我重用了很多代码,所以我在考虑尝试制作另一种有助于回收代码的方法,但我不确定这将如何满足独特的 getter 和 setter 的需要。
public void editQuery() {
}
// Edit BaseContact
public void edit(int id) {
try {
contacts.contains(contacts.get(id - 1));
} catch (IndexOutOfBoundsException e) {
System.out.println("Contact does not exist\n--- EXIT ---");
return;
}
Boolean active = true;
// While Statement for Edit
while (active) {
System.out.println(
"What property would you like to edit?\n1. Name\n2. Phone Number\n3. Date of Birth\n4. Hobby\n5. Description"
+ "\n6. Website URL\n7. Hours of Operation\n8. Street\n9. City\n10. State\n11. Zip Code\n12. Location"
+ "\n13. Relatives" + "\n14. Photos\n15. Exit");
String choice = sc.nextLine();
switch (choice.toUpperCase()) {
case "1":
case "NAME":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact Name: " + contact.getName() + "\n");
System.out.print("New Name: ");
String name = sc.nextLine();
contact.setName(name);
System.out.println("Contact Name Set To: " + contact.getName());
}
}
break;
case "3":
case "DATE OF BIRTH":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("Contact Date of Birth (ex. January 01, 1999): " + temp.getDob() + "\n");
System.out.print("New Date of Birth: ");
String dob = sc.nextLine();
temp.setDob(dob);
System.out.println("Contact Date of Birth Set To: " + temp.getDob());
}
}
}
break;
case "10":
case "STATE":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact State: " + contact.getLocation().getState());
System.out.print("New State: ");
String state = sc.nextLine();
contact.getLocation().setState(state);
System.out.println("Contact State Set To: " + contact.getLocation().getState());
}
}
break;
case "12":
case "LOCATION":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
// Location
Location location = createLocation();
contact.getLocation().setStreet(location.getStreet());
contact.getLocation().setCity(location.getCity());
contact.getLocation().setState(location.getState());
contact.getLocation().setZipCode(location.getZipCode());
System.out.println("Contact Location Set To: " + contact.getLocation());
}
}
break;
case "13":
case "RELATIVES":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("List of Relatives");
System.out.print("Contact Relatives: ");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println("Would you like to 1. Add or 2. Remove relatives?");
String rChoice = sc.nextLine();
// Adding Relative
if (rChoice.equalsIgnoreCase("1") || rChoice.equalsIgnoreCase("ADD")) {
System.out.println("--- Add Relatives ---");
System.out.println("List of Available Contacts\n");
for (BaseContact rcontact : contacts) {
if (rcontact.getType().equals("personContact")) {
PersonContact rtemp = (PersonContact) rcontact;
System.out.print(rtemp.getName() + " | ");
}
}
System.out.println();
System.out.println("How many relatives would you like to add?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Add Relative ---");
System.out.print("Relative Name: ");
String rname = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rname.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().add(r2temp);
}
}
}
}
// Removing Relative
} else if (rChoice.equals("2") || rChoice.equalsIgnoreCase("REMOVE")) {
System.out.println("--- Remove Relatives ---");
System.out.println("List of Relatives");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println();
System.out.println("How many relatives would you like to remove?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
if (numOfRelatives > temp.getRelatives().size()
|| numOfRelatives == temp.getRelatives().size()) {
temp.getRelatives().clear();
System.out.println("All Relatives Removed");
} else {
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Remove Relative ---");
System.out.print("Relative Name: ");
String rName = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rName.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().remove(r2temp);
}
}
}
}
}
} else {
System.out.println("Invalid Option");
}
}
}
}
break;
好吧,你会得到的。我主要查看了您正在进行的巨大的 switch 语句。对于初学者来说,这应该是浓缩的。更函数式的编程风格可以提供帮助。
我不得不根据代码中调用的方法推断出您使用的许多 classes。此外,我还挑选了几个 switch 表达式并将它们转换为更动态的内容。将此视为构建应用程序其余部分的起点。
开始为简单编辑创建操作 class:
public class ActionHolder {
private final String actionText;
private final BiConsumer<String, PersonContact> action;
private final Function<PersonContact, String> originalValFunc;
public ActionHolder(String actionText, BiConsumer<String, PersonContact> action,
Function<PersonContact, String> originalValFunc) {
this.actionText = actionText;
this.action = action;
this.originalValFunc = originalValFunc;
}
public String getActionText() {
return actionText;
}
public BiConsumer<String, PersonContact> getAction() {
return action;
}
public Function<PersonContact, String> getOriginalValFunc() {
return originalValFunc;
}
}
操作 class 在很大程度上依赖于函数式接口,请确保您通读它们,因为它们提供了一种强大的编程方式。 (https://www.baeldung.com/java-8-functional-interfaces)
- actionText:用于标记被编辑的属性。
- action:接受两个参数且 returns 什么都不接受的函数。
在这种情况下,我们将使用它来设置相应的值
联系人
- originalValFunc:从中检索原始值的函数
PersonContact,它是一个带一个参数的函数(PersonContact)
它 returns 一个字符串。
编辑方法可以构建如下:
class TestInputProgram {
public static void main(String[] args) {
TestInputProgram inputProgram = new TestInputProgram();
inputProgram.edit(1);
}
private final Scanner sc = new Scanner(System.in);
//Initialize with temp data
private final ArrayList<PersonContact> contacts = new ArrayList<PersonContact>() {{
add(new PersonContact(1));
}};
private static final Map<String, ActionHolder> actionMap = new HashMap<String, ActionHolder>() {{
put("1", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("NAME", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("3", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("DATE OF BIRTH", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("10", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
put("STATE", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
}};
// Edit BaseContact
public void edit(int id) {
while (true) {
System.out.println(
"What property would you like to edit?\n" +
"1. Name\n" +
"2. Phone Number\n" +
"3. Date of Birth\n" +
"15. Exit");
String choice = sc.nextLine();
if (Objects.equals(choice, "15")) {
break;
}
PersonContact pContact = contacts.stream()
.filter(contact -> contact.id == id)
.findFirst()
.orElseThrow(
() -> new IllegalArgumentException("Contact with id: " + id + " does not exist!")
);
Optional.ofNullable(actionMap.get(choice.toUpperCase())).ifPresent(actionHolder -> {
System.out.println(actionHolder.getActionText() + " current value: "
+ actionHolder.getOriginalValFunc().apply(pContact) + "\n");
System.out.println("Please provide the new value:");
String newValue = sc.nextLine();
actionHolder.getAction().accept(newValue, pContact);
System.out.println(actionHolder.getActionText() + " set to: "
+ actionHolder.getOriginalValFunc().apply(pContact));
System.out.println("############################# \n");
});
}
}
}
关于变量和发生的事情的一些简要信息:
actionMap 包含我们当前提供的所有可能的编辑选项。注意操作持有者参数的实现。我们使用 lamda 和静态方法引用来实现操作。在 edit 方法中查询地图并检索 actionHolder。然后将相应的输入操作信息打印给用户并要求输入。使用来自 actionHolder 的 (BiConsumer) 处理输入。
希望能为以后的编程优化提供一些参考。
在我的程序中,我试图创建一个方法来编辑 BaseContact 中的任何 属性。 BaseContact 是在 PersonContact 和 BusinessContact class 中扩展的抽象 class。我想创建一个编辑方法,询问用户 属性 他们想要编辑什么,向他们显示旧值,然后更新为他们想要的新值。我重用了很多代码,所以我在考虑尝试制作另一种有助于回收代码的方法,但我不确定这将如何满足独特的 getter 和 setter 的需要。
public void editQuery() {
}
// Edit BaseContact
public void edit(int id) {
try {
contacts.contains(contacts.get(id - 1));
} catch (IndexOutOfBoundsException e) {
System.out.println("Contact does not exist\n--- EXIT ---");
return;
}
Boolean active = true;
// While Statement for Edit
while (active) {
System.out.println(
"What property would you like to edit?\n1. Name\n2. Phone Number\n3. Date of Birth\n4. Hobby\n5. Description"
+ "\n6. Website URL\n7. Hours of Operation\n8. Street\n9. City\n10. State\n11. Zip Code\n12. Location"
+ "\n13. Relatives" + "\n14. Photos\n15. Exit");
String choice = sc.nextLine();
switch (choice.toUpperCase()) {
case "1":
case "NAME":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact Name: " + contact.getName() + "\n");
System.out.print("New Name: ");
String name = sc.nextLine();
contact.setName(name);
System.out.println("Contact Name Set To: " + contact.getName());
}
}
break;
case "3":
case "DATE OF BIRTH":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("Contact Date of Birth (ex. January 01, 1999): " + temp.getDob() + "\n");
System.out.print("New Date of Birth: ");
String dob = sc.nextLine();
temp.setDob(dob);
System.out.println("Contact Date of Birth Set To: " + temp.getDob());
}
}
}
break;
case "10":
case "STATE":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact State: " + contact.getLocation().getState());
System.out.print("New State: ");
String state = sc.nextLine();
contact.getLocation().setState(state);
System.out.println("Contact State Set To: " + contact.getLocation().getState());
}
}
break;
case "12":
case "LOCATION":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
// Location
Location location = createLocation();
contact.getLocation().setStreet(location.getStreet());
contact.getLocation().setCity(location.getCity());
contact.getLocation().setState(location.getState());
contact.getLocation().setZipCode(location.getZipCode());
System.out.println("Contact Location Set To: " + contact.getLocation());
}
}
break;
case "13":
case "RELATIVES":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("List of Relatives");
System.out.print("Contact Relatives: ");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println("Would you like to 1. Add or 2. Remove relatives?");
String rChoice = sc.nextLine();
// Adding Relative
if (rChoice.equalsIgnoreCase("1") || rChoice.equalsIgnoreCase("ADD")) {
System.out.println("--- Add Relatives ---");
System.out.println("List of Available Contacts\n");
for (BaseContact rcontact : contacts) {
if (rcontact.getType().equals("personContact")) {
PersonContact rtemp = (PersonContact) rcontact;
System.out.print(rtemp.getName() + " | ");
}
}
System.out.println();
System.out.println("How many relatives would you like to add?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Add Relative ---");
System.out.print("Relative Name: ");
String rname = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rname.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().add(r2temp);
}
}
}
}
// Removing Relative
} else if (rChoice.equals("2") || rChoice.equalsIgnoreCase("REMOVE")) {
System.out.println("--- Remove Relatives ---");
System.out.println("List of Relatives");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println();
System.out.println("How many relatives would you like to remove?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
if (numOfRelatives > temp.getRelatives().size()
|| numOfRelatives == temp.getRelatives().size()) {
temp.getRelatives().clear();
System.out.println("All Relatives Removed");
} else {
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Remove Relative ---");
System.out.print("Relative Name: ");
String rName = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rName.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().remove(r2temp);
}
}
}
}
}
} else {
System.out.println("Invalid Option");
}
}
}
}
break;
好吧,你会得到的。我主要查看了您正在进行的巨大的 switch 语句。对于初学者来说,这应该是浓缩的。更函数式的编程风格可以提供帮助。
我不得不根据代码中调用的方法推断出您使用的许多 classes。此外,我还挑选了几个 switch 表达式并将它们转换为更动态的内容。将此视为构建应用程序其余部分的起点。
开始为简单编辑创建操作 class:
public class ActionHolder {
private final String actionText;
private final BiConsumer<String, PersonContact> action;
private final Function<PersonContact, String> originalValFunc;
public ActionHolder(String actionText, BiConsumer<String, PersonContact> action,
Function<PersonContact, String> originalValFunc) {
this.actionText = actionText;
this.action = action;
this.originalValFunc = originalValFunc;
}
public String getActionText() {
return actionText;
}
public BiConsumer<String, PersonContact> getAction() {
return action;
}
public Function<PersonContact, String> getOriginalValFunc() {
return originalValFunc;
}
}
操作 class 在很大程度上依赖于函数式接口,请确保您通读它们,因为它们提供了一种强大的编程方式。 (https://www.baeldung.com/java-8-functional-interfaces)
- actionText:用于标记被编辑的属性。
- action:接受两个参数且 returns 什么都不接受的函数。 在这种情况下,我们将使用它来设置相应的值 联系人
- originalValFunc:从中检索原始值的函数 PersonContact,它是一个带一个参数的函数(PersonContact) 它 returns 一个字符串。
编辑方法可以构建如下:
class TestInputProgram {
public static void main(String[] args) {
TestInputProgram inputProgram = new TestInputProgram();
inputProgram.edit(1);
}
private final Scanner sc = new Scanner(System.in);
//Initialize with temp data
private final ArrayList<PersonContact> contacts = new ArrayList<PersonContact>() {{
add(new PersonContact(1));
}};
private static final Map<String, ActionHolder> actionMap = new HashMap<String, ActionHolder>() {{
put("1", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("NAME", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("3", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("DATE OF BIRTH", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("10", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
put("STATE", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
}};
// Edit BaseContact
public void edit(int id) {
while (true) {
System.out.println(
"What property would you like to edit?\n" +
"1. Name\n" +
"2. Phone Number\n" +
"3. Date of Birth\n" +
"15. Exit");
String choice = sc.nextLine();
if (Objects.equals(choice, "15")) {
break;
}
PersonContact pContact = contacts.stream()
.filter(contact -> contact.id == id)
.findFirst()
.orElseThrow(
() -> new IllegalArgumentException("Contact with id: " + id + " does not exist!")
);
Optional.ofNullable(actionMap.get(choice.toUpperCase())).ifPresent(actionHolder -> {
System.out.println(actionHolder.getActionText() + " current value: "
+ actionHolder.getOriginalValFunc().apply(pContact) + "\n");
System.out.println("Please provide the new value:");
String newValue = sc.nextLine();
actionHolder.getAction().accept(newValue, pContact);
System.out.println(actionHolder.getActionText() + " set to: "
+ actionHolder.getOriginalValFunc().apply(pContact));
System.out.println("############################# \n");
});
}
}
}
关于变量和发生的事情的一些简要信息: actionMap 包含我们当前提供的所有可能的编辑选项。注意操作持有者参数的实现。我们使用 lamda 和静态方法引用来实现操作。在 edit 方法中查询地图并检索 actionHolder。然后将相应的输入操作信息打印给用户并要求输入。使用来自 actionHolder 的 (BiConsumer) 处理输入。
希望能为以后的编程优化提供一些参考。