public class MyArrayList {
private Object store;
private int length;
public MyArrayList(Class<?> componentType) {
store = java.lang.reflect.Array.newInstance(componentType, 10);
}
}
这甚至可以生成int[]数组。我有意不在这里显示任何泛型,因为泛型不能是原始的。你根本不能生成任何类型的List<int>,句号。项目Valhalla可能会在未来的java版本中改变这一点,但是最新的java版本没有包含valhalla,而且在一段时间内不会。 一个更好的方法是多态性:创建一个abstract class AbstractList,然后进行多个实现:
public abstract class AbstractList<T> {
public abstract T get(int idx);
}
public final class IntList extends AbstractList<T> {
private int[] store = ...;
public Integer get(int idx) {
return store[idx];
}
}
class MyList<T> {
private Object[] data; // not T[] - you can't make those.
private int size;
public MyList() {
this.data = new Object[10];
this.size = 0;
}
public void add(T in) { // this ensures only Ts can be added
ensureCapacity();
this.data[size++] = in;
}
private void ensureCapacity() {
if (size == data.length) {
// Consider data.length*2 overflowing and such
// I'm keeping it (over-)simplified here
Object[] a = new Object[data.length * 2];
System.arraycopy(data, 0, a, 0, data.length);
data = a;
}
}
@SuppressWarnings("unchecked")
public T get(int idx) {
return (T) data[idx];
}
}
public class SillyArrayList<T> {
private final IntFunction<T[]> arrayMaker;
private T[] data;
private int size;
public SillyArrayList(IntFunction<T[]> arrayMaker) {
this.arrayMaker = arrayMaker;
data = arrayMaker.apply(10);
}
public void add(T in) {
ensureCapacity();
this.data[size++] = in;
}
private void ensureCapacity() {
if (size == data.length) {
// Consider data.length*2 overflowing and such
// I'm keeping it (over-)simplified here
T[] a = arrayMaker.apply(data.length * 2);
System.arraycopy(data, 0, a, 0, data.length);
data = a;
}
}
// no suppress needed
public T get(int idx) {
return data[idx];
}
}
// and to use:
SillyArrayList<String> myList = new SillyArrayList<>(String[]::new);
caller* 知道T是什么(它是String),所以我们让 * caller* 传入一个函数,该函数将把一个int转换为与该int一样大的正确类型的数组; String[]::new是size -> new String[size]的简写,size -> new String[size]是以下内容的简写:
class StringArrMaker implements IntFunction<String[]> {
@Override public String[] apply(int size) {
return new String[size];
}
}
return new StringArrMaker();
Object[] a = new String[10]; // legal
a[0] = LocalDate.now(); // compiles - but throws ArrayStoreException
System.out.println(a.getClass().getComponentType()); // prints String.
它是如此简单,只要创建一个类,你想要forex产品和定义字段和构造函数和getter & setter当创建一个对象从类简单地在一个数组列表中使用这List<Product> products list = new ArrayList<Product>();通过使用这一行,你正在创建一个对象在产品和存储int ArrayList
class Product{
int id;
String name;
float price;
public Product(int id, String name, float price) {
this.id = id;
this.name = name;
this.price = price;
}
}
public class JavaArrayListExample {
public static void main(String[] args) {
List<Product> productsList = new ArrayList<Product>();
//Adding Products
productsList.add(new Product(1,"HP Laptop",25000f));
productsList.add(new Product(2,"Dell Laptop",30000f));
List<Float> productPriceList = new ArrayList<Float>();
for(Product product: productsList){
// filtering data of list
if(product.price<30000){
productPriceList.add(product.price); // adding price to a productPriceList
}
}
System.out.println(productPriceList); // displaying data
}
}```
2条答案
按热度按时间tzxcd3kk1#
如何存储不同的数据类型?
有两种方法来“解读”这个问题。
我想存储
int
之类的基元,或者对象Java通常不能做到这一点。你可以动态地创建一个数组,这样就很灵活;数组本身就是对象。
这甚至可以生成
int[]
数组。我有意不在这里显示任何泛型,因为泛型不能是原始的。你根本不能生成任何类型的List<int>
,句号。项目Valhalla可能会在未来的java版本中改变这一点,但是最新的java版本没有包含valhalla,而且在一段时间内不会。一个更好的方法是多态性:创建一个
abstract class AbstractList
,然后进行多个实现:请再次注意
Integer
与int
的尴尬之处。我想存储一些特定的引用类型,例如
String
s ORLocalDate
s。数组被具体化并(不正确地)covariant,泛型是不变的并且被擦除。它们不会混合和匹配。这没有问题--你只需要自己写保证不会返回错误的类型,并添加适当的忽略警告代码。Object已经是你想要的一切了--毕竟,所有类型都是Object的子类型。因此,
Object[]
可以存储任何条带的任何引用类型,这实际上就是java已经存在的ArrayList
实现的工作方式:泛型被“擦除”,这意味着:编译器使用泛型以静默方式注入类型转换,并检查代码是否正确--在运行时,运行时什么也不做,也不知道泛型是什么,因此向
(T)
的类型转换实际上什么也不做:在运行时没有办法检查它,因为T在运行时消失了。你只是添加了那个强制转换,因为否则编译器会注意到你在返回T的时候返回了某个Object。编译器做不到这一点,但你的眼球和人脑可以:你知道,如果add()
方法只接受Ts,那么数组中的对象将是类型为T或T的某个子类型的对象,即使编译器不能确定,你也可以。所以,你添加了强制类型转换,并告诉编译器停止抱怨(添加@SuppressWarnings
),一切都很好。同样,
java.util.ArrayList
是如何做到的。但我真的想要一个
T[]
我想要一匹小马。你不能这样做。你唯一能做的就是接收一个
T[]
或接收可以制造它们的代码,你不能自己制造它们。如果你必须:String
),所以我们让 * caller* 传入一个函数,该函数将把一个int转换为与该int一样大的正确类型的数组;String[]::new
是size -> new String[size]
的简写,size -> new String[size]
是以下内容的简写:换句话说,我们传递一个可以生成数组的东西给你的数组列表,这样数组列表就可以使用 that,因为它自己不能生成
T[]
。然而,在一些情况下,这都是一堆毫无意义的废话--手动确保基本的数组列表代码是微不足道的(添加了一个不安全的(T)强制转换)实际上是100%安全的,不可能出错。(让它们实际上是
String[]
而不是Object[]
)是在运行时可以询问数组的类型,运行时将确保您不会将错误的内容放入:但是,如果
data
数组没有从数组列表中“泄漏”出来,也不应该“泄漏”出来(毕竟这是一个私有的实现细节),那么这一切都没有意义。这大概就是
ArrayList
使用Object[]
而不是T[]
+一个IntSupplier
的原因。sr4lhrrt2#
它是如此简单,只要创建一个类,你想要forex产品和定义字段和构造函数和getter & setter当创建一个对象从类简单地在一个数组列表中使用这
List<Product> products list = new ArrayList<Product>();
通过使用这一行,你正在创建一个对象在产品和存储int ArrayList