5 回答

TA貢獻1906條經驗 獲得超3個贊
關于檢查 foo
是集合還是數組的條件:
類#是可分配的可能
派上用場。
Class<?> fooClass = foo.getClass();
boolean isArrayOrCollection = Collection.class.isAssignableFrom(fooClass) ||
Object[].class.isAssignableFrom(fooClass);
我合理地假設你不會在基元數組上測試它,因為你有只使用包裝類的集合。
我想你可以安全地替換為Object[].class.isAssignableFrom(fooClass)fooClass.isArray()
boolean isArrayOrCollection = Collection.class.isAssignableFrom(fooClass) ||
fooClass.isArray();
它也適用于基元數組類。
我運行了一個小的“測試”
class Test {
public static void main(String[] args) {
Predicate<Class<?>> p = c -> Collection.class.isAssignableFrom(c) ||
c.isArray();
System.out.println(p.test(new int[0].getClass()));
System.out.println(p.test(new Integer[0].getClass()));
System.out.println(p.test(Collections.emptyList().getClass()));
System.out.println(p.test(Collections.emptySet().getClass()));
System.out.println(p.test(Collections.emptyMap().getClass()));
}
}
這導致
true
true
true
true
false
關于將同時在數組和集合上運行的泛型循環:
你根本無法寫一個準確的構造來處理這個問題:(或)并且幾乎沒有共同點(因為一個共同的父級及其方法是不夠的)。CollectionIterableObject[]Object
我認為構建自己的抽象是明智的,它將以相同的方式處理集合和數組。由于沒有特定的上下文,我可以想出兩個子類的簡單想法,每個子類都定義了它的源代碼(集合或數組)應該如何迭代。然后,對接口進行編程將有助于平等地管理它們。
一個非常簡化的例子是:
interface Abstraction<T> {
void iterate(Consumer<? super T> action);
static <T> Abstraction<T> of(Collection<T> collection) {
return new CollectionAbstraction<>(collection);
}
static <T> Abstraction<T> of(T[] array) {
return new ArrayAbstraction<>(array);
}
static IntArrayAbstraction of(int[] array) {
return new IntArrayAbstraction(array);
}
}
class CollectionAbstraction<T> implements Abstraction<T> {
Collection<T> source;
public CollectionAbstraction(Collection<T> source) {
this.source = source;
}
@Override
public void iterate(Consumer<? super T> action) {
source.forEach(action);
}
}
class ArrayAbstraction<T> implements Abstraction<T> {
T[] source;
public ArrayAbstraction(T[] source) {
this.source = source;
}
@Override
public void iterate(Consumer<? super T> action) {
for (T t : source) {
action.accept(t);
}
}
}
class IntArrayAbstraction implements Abstraction<Integer> {
int[] source;
public IntArrayAbstraction(int[] source) {
this.source = source;
}
@Override
public void iterate(Consumer<? super Integer> action) {
for (int t : source) {
action.accept(t);
}
}
}
class Test {
public static void main(String[] args) {
Abstraction.of(new Integer[] {1, 2, 3}).iterate(System.out::println);
Abstraction.of(Arrays.asList(1, 2, 3)).iterate(System.out::println);
Abstraction.of(new int[] {1, 2, 3}).iterate(System.out::println);
}
}
我相信上面的方法非常通用。您不依賴于某個源的迭代方式,您可以有選擇地修改它們。

TA貢獻1803條經驗 獲得超6個贊
其他答案都在努力回答原始標題問題:
數組和集合是否有通用接口或超類?
但你真正的問題是在身體里:
是否有其他可能性可以像上面這樣在一個循環中處理兩者?
答案是:不,沒有辦法編寫一個循環訪問集合和數組的 for
循環。
你可以跳過一堆箍,把數組變成列表,但你幾乎肯定會得到一個比你只寫兩個(或更多)循環更大的混亂。打電話會告訴你你有什么,但如果沒有某種演員,你仍然無法使用它。 不適用于基元數組。getClass().isArray()
Arrays.asList()

TA貢獻2003條經驗 獲得超2個贊
根據您要執行的操作,您可能需要實現兩種類似的方法:
public <T> void iterateOver(List<T> list) {
// do whatever you want to do with your list
}
public <T> void iterateOver(T[] array) {
this.iterateOver(Arrays.asList(array));
}
或者甚至可能有一個接口:
interface ExtendedIterableConsumer<T> {
public void iterateOver(List<T> list);
public default void iterateOver(T[] array) {
this.iterateOver(Arrays.asList(array));
}
我不確定這是否對你有幫助,因為你似乎已經在某個變量中擁有了有問題的對象。但是,如果你能把這個問題提高一個層次,它可能會很有用。

TA貢獻1825條經驗 獲得超6個贊
您可以使用來自isArray()Class
if (foo != null && (foo.getClass().isArray() || foo instanceof Collection<?>)){
}
編輯:
在迭代此對象方面,沒有簡單的解決方案。但是,您可以嘗試如下操作:foo
private void iterate(@NotNull Object foo) {
if (foo instanceof Collection<?>) {
for (Object o : ((Collection<?>) foo)) {
chandleYourObject(o);
}
}
if (foo.getClass().isArray()) {
if (foo.getClass().isPrimitive()) {
checkPrimitiveTypes(foo);
}
if (foo instanceof Object[]) {
for (Object o : (Object[]) foo) {
chandleYourObject(o);
}
}
}
}
private void checkPrimitiveTypes(Object foo) {
if (foo instanceof int[]) {
for (int i : (int[]) foo) {
}
}
//And the rest of primitive types
}
private void chandleYourObject(Object o ){
//What you want to do with your object
}

TA貢獻1859條經驗 獲得超6個贊
數組是對象:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html
抽象集合還擴展了對象:
https://docs.oracle.com/javase/8/docs/api/java/util/AbstractCollection.html
所以,是的,有一個普通的超類,但不幸的是,這并不能真正幫助你。
我建議你最好的選擇是使用:
List<> someList = Arrays.asList(sourceArray)
這會將您的數組轉換為實現 Iterable 的集合。您當然需要提前確定初始對象是數組還是集合,并且只有在數組時才調用上述內容,以下是一些執行此操作的選項:
boolean isArray = myArray.getClass().isArray(); boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());
添加回答
舉報