Java 值类型混淆

Java 值类型混淆,java,swift,class,value-type,Java,Swift,Class,Value Type,我关于StackOverflow的第一个问题:) 几天前,我开始在XCode中学习Swift,但在理解Swift中的值类型时遇到了一些困难。因为我对Java非常熟悉,所以我将用Java解释我的问题。以下是我想用Swift写的内容 class Node { public int value; public List<Integer> children; public Node parent; public Node() { value

我关于StackOverflow的第一个问题:)

几天前,我开始在XCode中学习Swift,但在理解Swift中的值类型时遇到了一些困难。因为我对Java非常熟悉,所以我将用Java解释我的问题。以下是我想用Swift写的内容

class Node {
    public int value; 
    public List<Integer> children;
    public Node parent;

    public Node() {
        value = 0;
        children = new ArrayList<Integer>();
    }

    public Node bestChild() {
        Node result = new Node();
        for (child : this.children) {
            if (child.value > result.value)
                result = child;
        }
        return result;
    }
}
public class Node {
    var value: Int
    var children: NSSet
    var parent: Node?

    public init() {
        self.value = 0
        children = NSSet()
    }

    public func bestChild() -> Node {
        var result = Node()
        for child in children {
            if (child.value > result.value) {      //error
                result = child                     //error
            }
        }
        return result
    }
}
if语句的条件和其中的行都有错误。XCode建议强制转换变量,但仍然没有解决错误

if ((child as AnyObject).value > result.value) {
    result = child as! Node
}
由于Java是我所知道的唯一语言,如果有人能用Java来解释它,我将不胜感激。如果没有,请保持简单,这样我就可以绕着它转:)


提前谢谢

欢迎使用堆栈溢出和快速编程

对Java代码的改进 首先,我建议对Java代码进行一些更改

  • 尽可能使用静态初始值设定项。这样做之后,您甚至不需要显式构造函数
  • 您的
    children
    变量的类型是
    List
    ,但我怀疑您的意思是
    List
  • 不要仅仅为了比较而创建新的
    节点
    。使用这种方法,如果
    bestChild()
    返回值为0的
    节点,则无法知道这是否是因为子列表为空,也无法知道是否确实存在值为0的
    节点
    ,该值为最高值。我将使用流API,尽管您可以手动实现这样的功能
  • 以下是最终结果:

    class Node {
        public int value;
        public List<Node> children = new ArrayList<>();
        public Node parent; // Unused?
    
        public Node bestChild() {
            // Modern, easy approach:
            return children
                   .stream()
                   .max((x, y) -> Integer.compare(x.value, y.value))
                   .get();
    
            // Old, classic Java approach:
            /*
            int max = Integer.MIN_VALUE;
            Node maxNode = null;
    
            for (Node child : this.children) {
                if (max < child.value) {
                    max = child.value;
                    maxNode = child;
                 }
            }
    
            return maxNode; */
        }
    }
    
    要解决解决方案尝试中的问题,请执行以下操作:
    NSSet
    是对
    Swift
    ,正如
    HashSet
    (没有泛型类型参数,不是
    HashSet
    )是对Java一样。它是为Objective-C发明的
    Foundation
    库中的数据类型。在99.999%的情况下,您不应该在Swift中使用它
    NSSet
    充当一组
    AnyObject
    。为了能够对集合中的对象调用
    .value
    ,您需要首先手动将对象强制转换到
    节点


    所有这些问题的解决方案都是改用
    Set
    ,这是Swift的原生
    Set
    数据结构。尽管这提出了一个问题,为什么在swift解决方案中使用集合,而在Java解决方案中使用数组?

    为什么使用
    NSSet
    [Int]
    不合适吗?您只需将
    NSSet
    更改为
    Set
    您的设计可能有问题,但如果您只是在学习,请不要担心这一部分。非常感谢您的回答!这段代码不是整个类,所以父类不是未使用的,实际上,我有多个构造函数,所以我没有初始化类变量。也就是说,如何在Swift中创建第二个“构造函数”。或者甚至有可能吗?请告诉我更多的信息(通过:{$0.value<$1.value}),这将非常有用。我没想到会有这么详细的答案。再次感谢你!一个类型中可以有任意多个初始值设定项,甚至可以将初始值设定项添加到非您自己的类中。您熟悉Java中的lambda表达式吗?斯威夫特的等价物被称为闭包,它们的设计明显更好,使用更方便
    {$0.value<$1.value}
    是一个闭包,它接受两个参数(均推断为
    Node
    类型)并返回
    Bool
    (根据
    
    
    class Node {
        let value = 0
        let children = [Node]()
        weak var parent: Node? // Unused?
    
        func bestChild() -> Node? {
            return children.max(by: { $0.value < $1.value })
        }
    }
    
    func bestChild() -> Node? {
        var max = Int.min
        var maxNode: Node?
    
        for child in children {
            if max < child.value {
                max = child.value
                maxNode = child
            }
        }
    
        return maxNode
    }