如何有效地寻找价值之间的映射?

时间:2019-02-23 21:00:52

标签: java

Map<Long, Object> map = new TreeMap<>();
map.put(100, object100);
map.put(120, object120);
map.put(200, object200);
map.put(277, object277);
map.put(300, object300);
map.put(348, object348);
map.put(400, object400);
//...

如果一个方法在地图的键和下一个地图的键之间获取值,则它将返回第一个键的对象。例如,如果使用值350调用搜索方法,则它应返回object348

键值的差异不是固定的。

但是要进行这样的搜索,需要遍历所有条目,直到获得正确的值为止。那么,如何提高效率?

2 个答案:

答案 0 :(得分:5)

对于要使用低于目标编号的键对象还是低于或高于最近键的对象,我并不确定。

我怀疑您只是在问以下密钥的对象,在这种情况下,NavigableMap.floorKey(K)应该找到了您想要的。

但是,以防万一您希望找到其键的值最近到目标值的对象,那么这应该可以满足您的要求:

import UIKit
import Foundation

protocol PopoverCellDelegate: class {
    func setPriority(buttonTitle: String)
}

class PopoverCell: UICollectionViewCell {
weak var delegate: PopoverCellDelegate?

let cellView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.white
    view.setCellShadow()
    return view
}()

let priorityButton: UIButton = {
    let button = UIButton(type: .custom)

    //        button.setImage(UIImage(named: "UnChecked"), for: .normal)
    //        button.setImage(UIImage(named: "Checked"), for: .selected)
    button.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
    button.setTitleColor(.black, for: .normal)
    button.backgroundColor = UIColor.white
    button.layer.borderWidth = 2
    button.layer.borderColor = UIColor.black.cgColor
    button.titleLabel?.font = UIFont.init(name: "Avenir Next", size: 24)
    return button
}()

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func prepareForReuse() {
    super.prepareForReuse()
    self.delegate = nil
}

override init(frame: CGRect) {
    super.init(frame: frame)
    setupCell()
    priorityButton.addTarget(self, action: #selector(setPriority), for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupCell() {
    cellView.translatesAutoresizingMaskIntoConstraints = false
    priorityButton.translatesAutoresizingMaskIntoConstraints = false

    addSubview(cellView)
    cellView.addSubview(priorityButton)

    cellView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
    cellView.setAnchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 8, paddingLeft: 4, paddingBottom: 8, paddingRight: 4)
    priorityButton.setAnchor(top: cellView.topAnchor, left: cellView.leftAnchor, bottom: cellView.bottomAnchor, right: cellView.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 60, height: 60)
    priorityButton.centerXAnchor.constraint(equalTo: cellView.centerXAnchor).isActive = true
}

@objc private func setPriority() {
    if let title = priorityButton.currentTitle {
        print(title)
        self.delegate?.setPriority(buttonTitle: title)
    }

}
}

请注意,如果目标编号与最接近的下方和最接近的上方的距离相等,则它将偏爱键值较低的对象。但是您只需在最终的public static Object findNearestTo(long targetNumber) { if (map.isEmpty()) { return null; // or throw an appropriate exception. } Object exactMatch = map.get(targetNumber); if (exactMatch != null) { return exactMatch; } Long nearestBelow = map.floorKey(targetNumber); Long nearestAbove = map.ceilingKey(targetNumber); if (nearestBelow == null) { return map.get(nearestAbove); } else if (nearestAbove == null) { return map.get(nearestBelow); } if (targetNumber - nearestBelow <= nearestAbove - targetNumber) { return map.get(nearestBelow); } else { return map.get(nearestAbove); } } 测试中将<=更改为<就可以支持较高的值。

答案 1 :(得分:1)

如评论中所指出,请检出NavigableMap。 方法map.floorEntry(key)应该做你想要的事情。