Java列表

时间:2015-10-03 00:21:15

标签: java list class

我试图创建一对整数列表。我认为我的基本想法是正确的,但每当我尝试在列表中添加新对时,我都会收到错误。

这是我的Pair班级:

public class Pair<L,R> {
    private L l;
    private R r;
    public Pair(L l, R r){
        this.l = l;
        this.r = r;
    }
    public L getL(){ return l; }
    public R getR(){ return r; }
    public void setL(L l){ this.l = l; }
    public void setR(R r){ this.r = r; }
}

这是我创建新对列表的地方:

private ArrayList<Pair<Short,Short>> DominoList = new ArrayList<Pair<Short,Short>>();

以下是我尝试向DominoList添加新配对的示例:

DominoList.add(0, Pair<0,0>);

有没有人看到我这样做的公然错误?我觉得我可能错过了一些简单的东西,但我无法弄清楚错误是什么。我觉得我正在错误地添加新对。

5 个答案:

答案 0 :(得分:2)

您应该调用构造函数来创建一个新的Pair实例。 使用

DominoList.add(0, new Pair(0, 0));

你说你想要成对的整数。那么你不应该使用Short而是使用Integer

答案 1 :(得分:0)

DominoList.add(new Pair(0, 0));

您还可以将内置类AbstractMap.SimpleEntry用作Pair类而不是自定义类。其他语言对简单元组有更好的支持,顺便说一句。

答案 2 :(得分:0)

除了其他答案(正确)之外,我还会提到Java中存在一种使用静态构造函数而不是new的常见模式;那就是:

public class Pair<L, R> {
  // other code
  public static <L, R> Pair<L, R> of(L left, R right) {
    return new Pair(left, right);
  }
}

这使您可以更优雅地使用它:

DominoList.add(Pair.of(0, 0));

如果您想探索它,还有一个提供此功能的库:Apache Commons Lang

答案 3 :(得分:0)

您需要通过在其他人提到的Pair类之前插入new关键字来创建类的新实例。

因此,您的代码应为:

private final List<Pair<Short,Short>> dominoList = new ArrayList<>();
dominoList.add(new Pair(0, 0));

我认为值得一提的是一些小变化。

首先,如果您使用的是Java 7或8,则无需在两端显式使用泛型类型。

另请注意,最好在变量中引用接口而不是具体类型。在这种情况下,最好使用List而不是ArrayList。通过执行此操作,您可以稍后更改列表实现,例如,LinkedList具有与ArrayList不同的性能属性。

其次,由于您在声明中初始化变量,因此将其标记为final也是一种好习惯。通过这样做,您可以帮助编译器优化您的字节码,并在您不必要地为变量分配新实例时获得一些反馈。

在您的具体情况下,您可能还想查看其他集合,例如Map<K,V>。您可以轻松地将一个整数键映射到另一个整数值,但要小心选择地图实现,例如,HashMap不允许重复键。

其中一些提示可以在以下网址找到:

  • Joshua Bloch的有效Java
  • Maurice Naftalin和Philip Wadler的Java Generics and Collections

恕我直言,两者都是必要的阅读,以便更好地理解和编码Java。

答案 4 :(得分:0)

  

有人在我做这件事的方式上有什么公然错误吗?

您的命名可能会得到改善。使用单字母缩写会造成混淆。我假设您的意思是“左”和“右”。如果那是您的意思,那就这么说。

此外,如果确实的意思是左右,我认为您之所以选择它是因为您从左到右阅读。但是对于许多阅读从右到左语言(例如阿拉伯语,希伯来语,波斯语和乌尔都语信德语)的人来说,这是没有意义的。更好的是诸如“前导”和“尾随”,或者通用的“关键”和“值”。

此代码是错误的,因为它说您有一个名为L的类和一个名为R的类。但是显然你没有。您实际上是在存储一对Short对象,所以请指定Short

private L l;
private R r;
public Pair(L l, R r){

...应该是...

private Short key ;
private Short value ;
public Pair( Short key , Short value ){

另一个命名问题:Java约定说,一个类以大写字母命名,而实例变量则以小写字母命名。所以这个:

private ArrayList<Pair<Short,Short>> DominoList = new…

…在d上应该用小写的dominoList

private ArrayList<Pair<Short,Short>> dominoList = new…

上面紧跟该代码段的另一件事:如果更通用的界面提供了后续代码所需的所有行为,通常我们使用List或左侧。这是polymorphism的一个方面,允许您将来将ArrayList换成其他List的实现,而无需使用该列表来更改或破坏任何其他代码。

Map.Entry

  

我可能缺少一些简单的东西

更简单的方法是使用内置于Java中的现有类。有些人将Map.Entry接口的任一实现作为配对类使用:

immutable版本意味着键部分和值部分都不能替换为另一个对象。存储为键或值的对象本身可能是可变的(具有可以通过诸如setter方法更改的状态)。

示例:

List < AbstractMap.SimpleImmutableEntry < Short, Short > > dominoList = new ArrayList <>( 28 );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 0 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 1 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 1 , 1 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 2 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 1 , 2 ) );

应用上述多态性原则,我们应该将列表定义为包含更通用的Map.Entry接口。

List < Map.Entry < Short, Short > > dominoList = new ArrayList <>( 28 );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 0 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 1 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 1 , 1 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 0 , 2 ) );
dominoList.add( new AbstractMap.SimpleImmutableEntry( 1 , 2 ) );

当然,有人会认为Entry.Map的这种使用是黑客。这些类旨在在Map中使用。但是没有技术上的理由禁止您单独使用条目类。

如果您将这些数字对用作地图,第一个是第二个的名称或标识符,那么我建议您实际上使用Map实现而不是List。但是我怀疑你不是。

Domino

diagram of all 28 tiles in a set of dominoes

如果您要对domino tiles进行建模,则实际上应该定义自己的Domino类。您不仅具有一对数字来表示,而且还可以具有其他方法,例如isDouble

如果您要构建一个更大的上下文来显示这些多米诺骨牌,例如游戏,那么具有特定的命名类将使您的代码更self-documentingthread-safe