java - 值类型困惑

标签 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 = 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;
    }
}

为了这个问题,我们在这里不讨论私有(private)、公共(public)或通用。保持简单即可! 这是我在 Swift 中的尝试。

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 来解释它,我将不胜感激。如果没有,请保持简单,以便我可以理解它:)

提前致谢!

最佳答案

欢迎来到 Stack Overflow 和 Swift 编程!

Java 代码的改进

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

  1. 尽可能使用静态初始化器。完成此操作后,您甚至不需要显式构造函数。
  2. 您的children变量的类型为 List<Integer> ,但我怀疑你的意思是 List<Node> .
  3. 不要创建新的 Node只是为了比较。通过这种方法,如果 bestChild()返回 Node值为 0 时,无法知道这是否是因为子列表为空,或者是否确实存在 Node值为 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; */
    }
}

Swift 等效

这是我用 Swift 编写的方法。欢迎提出后续问题

class Node {
    let value = 0
    let children = [Node]()
    weak var parent: Node? // Unused?

    func bestChild() -> Node? {
        return children.max(by: { $0.value < $1.value })
    }
}

过时的 Java 方法的 Swift 等效项

这是对 bestChild 过时的 Java 方法的 Swift 实现方法。这只是为了比较。 不要这样做!

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
}

要解决解决方案尝试中的问题:

NSSetSwift ,如HashSet (没有泛型类型参数,不是 HashSet<T> )是针对 Java 的。它是 Foundation 中的数据类型库,是为 Objective-C 发明的。在 99.999% 的情况下,你不应该在 Swift 中使用它。 NSSet充当一组 AnyObject 。为了能够调用.value对于集合中的一个对象,您需要首先手动将该对象转换为 Node .

解决所有问题的方法是使用 Set<Int> ,这是 Swift 的原生 Set数据结构。虽然这提出了一个问题,为什么在 swift 解决方案中使用 Set,而在 Java 解决方案中使用数组?

关于java - 值类型困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364830/

相关文章:

java - Lucidworks 保存 solr 格式未知字段

java - 使用随机逗号或点分隔符从文件中解析 double

ios - 点击/向后滑动时图像与之前的 View 重叠

java - 泛型类声明中的泛型类型

java - Jersey 的 JSON MediaType

ios - 使用 Realm 存储来自 Foursquare 的附近位置

swift - 类型 'X' 的值没有成员 'y' - 协议(protocol)中的可选函数

java - 从另一个类调用方法时遇到问题

java - 在接口(interface)中编写类有什么用

java - 无法在我的 JavaScript 客户端上解码我的 Base64 字符串