首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用混合数据类型在泛型中初始化数组

如何使用混合数据类型在泛型中初始化数组
EN

Stack Overflow用户
提问于 2019-08-31 14:46:22
回答 6查看 179关注 0票数 1

我正在研究Java数组,另外,我还在研究泛型。下面是初始化数组的两种方法

代码语言:javascript
复制
int[] data = {1,2,3,4,5,6,7,8,9};

// or

int[] data;
data = new int[] {1,2,3,4,5,6,7,8,9};

但是当我使用泛型时,我有多种数据类型--例如,

代码语言:javascript
复制
String[] outcome = {"0 wins", "Tie" , "X wins"};

上面的数组只有一个字符串的数据类型。如果在数组中,我有如下所示

代码语言:javascript
复制
outcome = {7, "Tie" , 9.0};

现在,我在数组中混合了数据类型。我是怎么写的,或者是否可以用泛型来写?我能用ArrayList做吗?

谢谢

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2019-08-31 15:16:07

tl;dr:在我看来,数组并不适合这个问题,您应该使用对象。

这不是对你问题的直接回答,而是一个重新设计的回答。

首先,让我们讨论一下您关于泛型和数组的声明。数组是协变和保留的,而泛型是不变的和擦除的。

  • 协变量意味着当B extends A时,您可以编写A[] aArray = new B[someSize];不变意味着这是不可能的:ArrayList<A> aList = new ArrayList<B>();将导致编译时错误。
  • retained 意味着在运行时保留有关类型的信息:数组总是“知道*其元素的类型”。擦除意味着类型信息在编译后消失。这也称为类型擦除

混合古雅和保留与不变和擦除有很好的潜力,使你陷入麻烦。这就是为什么作为其支持数据结构

现在是实际的问题。正如其他人已经说过的,我们可以沿着这条路走下去,创建一个Object[]。我强烈建议不要这样做,因为我们丢失了所有类型的信息。获取这些信息的唯一方法是进行instanceof检查,这会使您的代码变得僵硬。假设您更改了条目的类型。在这种情况下,instanceof将返回false,可能会导致不必要的行为,(最好的情况)一些测试会变红,或者(最坏的情况)我们可能不会注意到它。

现在怎样才能避开这一切?我们创建一个类来表示(我推断的)匹配结果:

代码语言:javascript
复制
public class MatchResult {
    private final int firstTeamScore;
    private final int secondTeamScore;

    public MatchResult(final int firstTeamScore, final int secondTeamScore) {
        this.firstTeamScore = firstTeamScore;
        this.secondTeamScore = secondTeamScore;
    }

    public int getFirstTeamScore() {
        return firstTeamScore;
    }

    public int getSecondTeamScore() {
        return secondTeamScore;
    }

    public String getResultForFirstTeam() {
        if (firstTeamScore > secondTeamScore) {
            return "Win"; // In an actual implementation, I would replace this with an enum
        } else if(firstTeamScore = secondTeamScore) {
            return "Tie";
        } else {
           return "Lose";
        }
    }
    // You can add a method public String getResultForSecondTeam(), I omitted it for brevity
}

我们赢了什么?我们有类型的。分数总是ints,结果总是Strings。例如,如果我们将getReultforFirstTeam()的类型从String改为Enum,我们就会得到该类型不再匹配的所有位置的编译器错误。因此,我们磨练了防故障设计,并被迫在必要时修改代码。因此,我们甚至没有机会得到我们以前有过的偷偷摸摸的、不受欢迎的行为。

票数 1
EN

Stack Overflow用户

发布于 2019-08-31 14:58:38

我想纠正这一点:

但是当我使用泛型时,数据类型是混合的。

泛型需要同构的数据类型。例如,List<Integer>是一个只能容纳Integer的列表,而List<? extends Number>永远只能容纳Number,它涵盖了单个类型Number所引用的其他数字类型,如LongShortDouble、etc...but。

不管怎么说,你要找的是一个袋子-一个可以容纳任意物体的集合。您可以使用Object[]List<Object>来实现这一点,并且当您想要使用它时,必须检查提取出来的每个元素的类型,因为在Java中没有方法可以拥有异构数据类型,这正是您要寻找的。

票数 2
EN

Stack Overflow用户

发布于 2019-08-31 14:47:49

1处理此问题的方法是创建一个Object数组,该数组可以容纳所有数据类型。

代码语言:javascript
复制
Object[] outcome = {7, "Tie" , 9.0};

稍后,您可以访问以下对象:

代码语言:javascript
复制
if(outcome[0] instanceof Integer){
   Integer i = (Integer) outcome[0];
}

反之亦然。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57738998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档