gpt4 book ai didi

java - 在构建容器时,为什么使用 Java 泛型比使用对象类更好? (Java 泛型和数据结构)

转载 作者:行者123 更新时间:2023-12-02 01:17:13 25 4
gpt4 key购买 nike

所以我一直在回顾我的数据结构,并发现了一个关于 Java 泛型和 Object 类的有趣想法。我以两种不同的方式实现和运行“通用包”(注意下面:IObjectBag.java、ObjectBag.java、IGenericBag.java 和 GenericBag.java) 并使用它们 (注意:在 main.java 和输出下方)。我已经根据堆栈溢出规则删除了一些不必要的代码,但如果您想要完整的实现,请告诉我。

此外,除了查看 ArrayList 类的源代码 here 之外,我还在许多网站、书籍和类(class)中研究了该主题。我知道我的 GenericBag 是比我的 ObjectBag 更好的选择,但还不足以在面试中以实用的方式解释它。我很困惑的是,我的 GenericBag 在其实现中比我的 ObjectBag 使用了更多的转换操作(请参阅 RemovePrintBag )。

  1. 那么,除了语法糖之外,为什么我的 GenericBag 更好?请以我的类(class)为例。

  2. 在运行时/开销/空间/时间方面是否存在我没​​有注意到的重要差异?

  3. 您会如何回答这个问题或期望在面试中得到回答?

奖励问题:如果您愿意,请回答 MainGenericBag 评论中的奖励问题(我想我可以自己回答)不过,只是想听听您的意见)。

IObjectBag接口(interface):

public interface IObjectBag {
void add(Object item);
Object remove(Object item) throws NoSuchElementException;
boolean isEmpty();
int find(Object item);
Object get(int index);
int numItems();
}

ObjectBag 类:

public class ObjectBag implements IObjectBag {
private Object [] items; // the java class attribute that will hold out "ints"
private int numItems;

public static void printBag(IObjectBag bag) {
for(int i = 0; i < bag.numItems(); i++) {
System.out.println(bag.get(i));
}
}

public ObjectBag(int size) {
this.items = new Object[size]; // fills array with null values
this.numItems = 0;
}

public void add(Object item){
// adds item to end of bag
}

public Object remove(Object item) {
int index = this.find(item);

if(index == -1) throw new NoSuchElementException("oops nothing found");

Object out = this.items[index];

this.items[index] = null;
this.numItems -= 1;

if(index + 1 != this.items.length && this.items[index + 1] != null) {
for(int i = index; i < this.items.length; i++) {
if(i + 1 != this.items.length) this.items[i] = this.items[i + 1];
}

this.items[this.items.length - 1] = null;
}

return out;
}

public int find(Object item) {
// return index given item or -1
}

public Object get(int index) {
// returns item given index
}

}

IGenericBag 类:

public interface IGenericBag <T> {
void add(T item);
T remove(T item) throws NoSuchElementException;
boolean isEmpty();
int find(T item);
T get(int index);
}

GenericBag 类:

public class GenericBag<T> implements IGenericBag<T> {
// private T[] items; can't use this b/c see comment in constructor
private Object[] items;
private int numItems;

public static void printBag(GenericBag bag) {
for(int i = 0; i < bag.numItems(); i++) {
System.out.println(bag.get(i));
}
}

public GenericBag(int size) {
// this.items = new T[size]; Bonus: throws generic array creation error (why?)
this.items = new Object[size];
this.numItems = 0;
}

public void add(T item){
this.items[this.numItems] = item;
this.numItems += 1;
}

public T remove(T item) {
int index = this.find(item);

if(index == -1) throw new NoSuchElementException("oops nothing found");

T out = (T) this.items[index];

this.items[index] = null;
this.numItems -= 1;

if(index + 1 != this.items.length && this.items[index + 1] != null) {
for(int i = index; i < this.items.length; i++) {
if(i + 1 != this.items.length) this.items[i] = this.items[i + 1];
}

this.items[this.items.length - 1] = null;
}

return out;
}

public int find(Object item) {
// given object return index or throw exception
}

public T get(int index) {
return (T) this.items[index];
}

}

类:

public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello StackOverFlow!");
Object int1 = new Integer(1);
Object int2 = new Integer(2);
Object int3 = new Integer(3);


/* using my object bag ************************************************/
System.out.println("using my object bag");
IObjectBag myObjectBag = new ObjectBag(3);

myObjectBag.add(int1);
myObjectBag.add(int2);
myObjectBag.add(int3);
myObjectBag.remove(int2);

ObjectBag.printBag(myObjectBag);

/* using my generic bag ***********************************************/
System.out.println("using generic bag");


// Bonus Question: using object like above causes error at add method (why?)
Integer int4 = new Integer(4);
Integer int5 = new Integer(5);
Integer int6 = new Integer(6);

GenericBag<Integer> myGenericBag = new GenericBag<Integer>(3);
//Bonus Question: using Interface decllaration like above causes error in print bag (why?)

myGenericBag.add(int4);
myGenericBag.add(int5);
myGenericBag.add(int6);
myGenericBag.remove(int4);

GenericBag.printBag(myGenericBag);
}

}

输出:

Hello StackOverFlow!
using my object bag
1
3
using generic bag
5
6

最佳答案

ObjectBag 的问题可通过 GenericBag 实现提供的类型安全“自动”解决:

  • 访问条目会返回 Object,此时您不知道 Object 是什么类型。
  • 您可以在同一个列表中插入任何类型的对象(混合),例如字符串和整数,这是一种反模式,会导致代码不可读(用您的泛型包尝试一下!)
  • 因为您的编译器在您声明 GenericBag 后就知道它的类型,所以在代码的任何阶段,如果您将鼠标悬停在 genericBag 实例上,您就会知道它的类型,这使得您的代码对于其他人来说更具可读性和可扩展性

泛型还提供更多功能,假设您希望您的 GenericBag 只接受数字,那么您可以按如下方式编写:

public class GenericBag<T extends Number>

我给你的建议是阅读一些关于 Java 基础知识的文章,尤其是泛型,有基于实践的学习方式是一件好事,但是有很多文章可以为你提供一些关于这个问题的非常好的理论见解。

https://www.baeldung.com/java-generics

关于java - 在构建容器时,为什么使用 Java 泛型比使用对象类更好? (Java 泛型和数据结构),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58362531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com