【问题标题】:Java: How to access an instance variable in a ternary operator?Java:如何在三元运算符中访问实例变量?
【发布时间】:2018-09-28 03:29:34
【问题描述】:

这是 ListNode 类:

  public class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
  }

我正在尝试像这样初始化 PriorityQueue:

PriorityQueue<ListNode> heap = new PriorityQueue(lists.length,
            (l1, l2) -> l1.val < l2.val ? -1 :
                        l1.val == l2.val ? 0 :
                        1);

但我得到“找不到符号:变量 val”。这样做的正确方法是什么?我尝试将 l1 和 l2 转换为 ListNode,但这没有任何作用。

编辑:为什么会这样?

    PriorityQueue<ListNode> queue= new PriorityQueue<ListNode>(lists.size(),new Comparator<ListNode>(){
            @Override
            public int compare(ListNode o1,ListNode o2){
                if (o1.val<o2.val)
                    return -1;
                else if (o1.val==o2.val)
                    return 0;
                else 
                    return 1;
            }
        });

【问题讨论】:

  • public int val; 你有它作为包级别。还有Integer.compare(l1.val, l2.val);
  • 但是为什么我可以在三元运算符之外访问它们呢?
  • 我看到了一个编辑。在下面查看我的答案。它建议实现 Comparable 接口并将比较方法放入 ListNode。比较器是具有相似意图的不同事物。
  • 谢谢。原来我的问题是语法错误。我忘了在括号前添加

标签: java priority-queue ternary-operator


【解决方案1】:

您缺少右侧的菱形运算符,这使编译器无法将参数类型推断为ListNode(它推断为对象,因此您无法访问val

试试这个

 PriorityQueue<ListNode> heap = new PriorityQueue<>(lists.length,
            (l1, l2) -> l1.val < l2.val ? -1 :
                    l1.val == l2.val ? 0 :
                            1);

我的初步回答:

如果您的 PriorityQueue 声明位于不同的包中(与声明 ListNode 的包不同):

它与三元运算符无关。变量val 是包私有的。将其公开将解决问题,但这不是一个好的做法。相反,为它添加一个 getter 并将实例变量设为私有(除非你有理由将它们设为包私有)

public int getVal() {
    return val;
}


PriorityQueue<ListNode> heap = new PriorityQueue<>(lists.length,
        (l1, l2) -> l1.getVal() < l2.getVal() ? -1 :
                    l1.getVal() == l2.getVal() ? 0 :
                    1);

【讨论】:

  • 但是我可以在三元运算符之外访问它们。我可以创建一个 ListNode 对象并访问它之外的变量。
  • 很可能,您尝试从 同一个包 或命名空间访问 val,而 PriorityQueue 声明位于不同的包中
  • 谢谢。我在 LeetCode 上做这个,所以我无法访问那些东西。还要感谢任何对我投反对票的人。这就是我讨厌在这里提问的原因。
  • @JohnTravicks 顺便说一句,我没有投反对票。人们应该在在这里提问之前做一些研究。如果您尝试搜索错误,您会得到这个答案。但我可以理解你被误导认为这是由于三元运算符。
  • 您能解释一下为什么我的编辑中的解决方案有效吗?与三元运算符相比,访问 val 的方式有什么不同?
【解决方案2】:

int val 更改为public int val

或者创建一个getter方法并使用它

    public class ListNode {
         public int val;
         ListNode next;
         ListNode(int x) { val = x; }
     }

【讨论】:

  • 谢谢。原来我的问题是语法错误。我忘了在括号前添加
  • 天哪!我也错过了
【解决方案3】:

@user7 有一个正确的答案,但我会在这里提出不同的最佳做法:

ListNode上实现接口Comparable&lt;ListNode&gt;,并将比较函数放在ListNode类实现中。然后只需使用

new PriorityQueue<ListNode>()

它会使用元素的“自然顺序”

【讨论】:

  • 谢谢。原来我的问题是语法错误。我忘了在括号前添加
  • 忘记 不是语法错误。它有助于 Compiler 了解您尝试执行的操作。但是,是的,使用遗传学 将有助于编译器(并且它将帮助开发人员):)。在这种情况下使用 Comparable。仍然是首选方式:这种方式 ListNode 知道自己对其他 ListNodes 的优先级。不是您创建队列的“外部程序”。
  • PS:在我的回答中也添加了泛型 :)
【解决方案4】:

我找到了答案。这是一个语法错误。

PriorityQueue<ListNode> heap = new PriorityQueue<>(lists.length,
            (l1, l2) -> l1.val < l2.val ? -1 :
                        l1.val == l2.val ? 0 :
                        1);

这行得通。

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 2011-03-12
    • 2015-01-09
    相关资源
    最近更新 更多