Java 循环以获取距离输入值最近的对象

Java 循环以获取距离输入值最近的对象,java,loops,arraylist,compare,Java,Loops,Arraylist,Compare,我有一门火星课程: public abstract class Martian implements Cloneable { int id; public Martian(int id) { this.id = id; } public Object clone() throws CloneNotSupportedException { return super.clone(); } public int getId() { return id; } public bo

我有一门火星课程:

public abstract class Martian implements Cloneable {
int id;

public Martian(int id) {
    this.id = id;
}
public Object clone() throws CloneNotSupportedException {
    return super.clone();
}
public int getId() {
    return id;
}
public boolean equals(Object o){
    if( o != null);
    return this.getId() == ((Martian)o).getId();    
}
public abstract void speak();

public String toString(){
    return "Martian" + getId(); 
}       
} 
还有一个火星经理课程:

public class MartianManager {
private ArrayList<Martian> martians;
private ArrayList<Martian> teleporters;

public void addMartian(Martian m) {
    martians.add(m);
    if(m instanceof GreenMartian)
        teleporters.add(m);
}
//public Object clone() {

public Martian getMartianClosestToID(int id) {

}
public void groupSpeak() {
    for(Martian m : martians) {
        m.speak();
    }
}
public void groupTeleport(String dest) {
    for (Martian m : martians){
        if (m instanceof GreenMartian)
            ((GreenMartian) m).teleport(dest);
    }   
}
//public obliterateTeleporters() 

//removeMartian(int id)
}
公共类管理器{
私人ArrayList火星人;
私人ArrayList传送机;
火星人(火星人m){
加上(m);
if(绿色火星的m实例)
传送者。添加(m);
}
//公共对象克隆(){
公共火星人GetMartianCloseStoid(int id){
}
公共演讲{
对于(火星人m:火星人){
m、 说();
}
}
公共空组传送(字符串目的地){
对于(火星人m:火星人){
if(绿色火星的m实例)
(绿色火星人)m.传送(目的地);
}   
}
//公共隐形传送者()
//removeMartian(内部id)
}

MartianManager
类中,我有一个方法
getMartianCloseStoid()
返回的火星人的id与输入id最接近。我的问题基本上是在循环中使用什么最简单的逻辑来实现这一点,或者它们是一种更简单的方法,比如
比较到
,我不知道比较在这种情况下是否会起作用。

类似的东西应该会起作用

这是否正是你想要的取决于一些假设。id是唯一的吗?一个火星人能离自己最近吗?如果有两个同样接近的火星人呢?或者没有其他火星人呢?我假设“id”参数可能是集合中的一个id,而你不想要那个

但最大的问题是:“最近”是什么意思?亲密度的概念通常不适用于ID

public Martian getMartianClosestToId(int id) {
    Martian closest = null;
    int leastDist = -1;
    for(Martian m : martians) {
        int mId = m.getId();
        if(mId == id)
             continue; // Skip the Martian with the same id.
        int d = Math.abs(mId - id);
        if(leastDist == -1 || d < leastDist) {
            leastDist = d;
            closest = m;
        }
    }
    return closest;
}
public火星人getMartianCloseStoid(int-id){
火星近邻=零;
int leastDist=-1;
对于(火星人m:火星人){
int mId=m.getId();
if(mId==id)
继续;//跳过具有相同id的火星人。
intd=Math.abs(mId-id);
如果(leastDist==-1 | | d

我还没有编译/测试过这个-您可能需要修复打字错误。

类似的东西应该可以工作

这是否正是你想要的取决于一些假设。id是唯一的吗?一个火星人能离自己最近吗?如果有两个同样接近的火星人呢?或者没有其他火星人呢?我假设“id”参数可能是集合中的一个id,而你不想要那个

但最大的问题是:“最近”是什么意思?亲密度的概念通常不适用于ID

public Martian getMartianClosestToId(int id) {
    Martian closest = null;
    int leastDist = -1;
    for(Martian m : martians) {
        int mId = m.getId();
        if(mId == id)
             continue; // Skip the Martian with the same id.
        int d = Math.abs(mId - id);
        if(leastDist == -1 || d < leastDist) {
            leastDist = d;
            closest = m;
        }
    }
    return closest;
}
public火星人getMartianCloseStoid(int-id){
火星近邻=零;
int leastDist=-1;
对于(火星人m:火星人){
int mId=m.getId();
if(mId==id)
继续;//跳过具有相同id的火星人。
intd=Math.abs(mId-id);
如果(leastDist==-1 | | d

我还没有编译/测试过这一点-您可能需要修复打字错误/错误。

我认为这比目前为止的其他答案更简单(OP要求“最简单的逻辑”):

public火星人getMartianCloseStoid(int-id)
{
if(martians==null | | martians.isEmpty())
返回null;
火星人结果=火星人。获取(0);
对于(火星人m:火星人)
if(Math.abs(id-m.getId())
我认为这比目前为止的其他答案更简单(OP要求“最简单的逻辑”):

public火星人getMartianCloseStoid(int-id)
{
if(martians==null | | martians.isEmpty())
返回null;
火星人结果=火星人。获取(0);
对于(火星人m:火星人)
if(Math.abs(id-m.getId())
这不是最简单的,但在很多情况下,这将是最快的

如果您愿意让您的火星人列表始终按id排序(如果您不经常添加火星人,这很容易做到,您可以在添加火星人时进行排序),您可以这样做:

Comparator<Martian> compareById = new Comparator<Martian>() {
    public int compare(Martian a, Martian b) {
        return Integer.compare(a.getId(), b.getId());
    }
}
现在,您将知道它应该去哪里,您将有五个选项之一:

  • 该位置具有您要查找的id。如果是,请返回火星人。获取(位置)
  • 提供的位置不在列表中,这意味着您正在寻找低于最低或高于最高的位置。 2.a.低于最低值:返回最低值,火星人。获取(0); 2.b.高于最高值:返回最高值,martians.get(martians.length()-1)
  • 该位置高于您要查找的id。(不会更低,否则您将得到比您所查找的低1的结果!)因此,请查看火星人。获取(位置)和火星人。获取(位置-1),查看您最接近的一个,并返回相应的一个
  • 这有一个昂贵的前期成本(排序),但在你把它排序后,你可以使用二进制搜索,这是非常便宜的,每次都可以非常快地找到最近的火星人

    如果你打算经常添加,那么我建议将新的火星人添加到末尾,并将你的收藏标记为未排序,然后只在你即将找到一个时进行排序

    public Martian getMartianClosestToID(int id) {
        if(!martiansAreSorted) Collections.sort(martians,compareById);
        int loc = Collections.binarySearch(martians,id,compareById);
        if(loc >= 0) return martians.get(loc); // found exact match
        // we know loc is negative because it wasn't found - read the docs
        loc = -loc;
        if(loc == 0) return martians.get(0);
        if(loc == martians.size()) return martians.get(loc - 1);
        Martian high = martians.get(loc);
        Martian low = martians.get(loc - 1);
    
        int highid = high.getId();
        int lowid = low.getId();
    
        int highdiff = Math.abs(id - highid);
        int lowdiff = Math.abs(id - lowid);
    
        if(highdiff < lowdiff) return high;
        return low;
    
    }
    
    public火星人getMartianCloseStoid(int-id){
    if(!martiansarestored)Collections.sort(martians,compareById);
    int loc=Collections.binarySearch(martians,id,compareById);
    如果(loc>=0)返回火星人。获取(loc);//找到精确匹配
    //我们知道loc是阴性的,因为它没有找到-请阅读文档
    loc=-loc;
    如果(loc==0)返回火星人,则获取(0);
    if(loc==martians.size())返回martians.get(loc-1);
    火星高=火星人。获取(loc);
    火星人低=martians.get(loc-1);
    int highid=high.getId();
    int lowid=low.getId();
    int highdiff=Math.abs(id-highid);
    int lowdiff=Math.abs(id-lowid);
    if(高差<低差)retu
    
    public Martian getMartianClosestToID(int id) {
        if(!martiansAreSorted) Collections.sort(martians,compareById);
        int loc = Collections.binarySearch(martians,id,compareById);
        if(loc >= 0) return martians.get(loc); // found exact match
        // we know loc is negative because it wasn't found - read the docs
        loc = -loc;
        if(loc == 0) return martians.get(0);
        if(loc == martians.size()) return martians.get(loc - 1);
        Martian high = martians.get(loc);
        Martian low = martians.get(loc - 1);
    
        int highid = high.getId();
        int lowid = low.getId();
    
        int highdiff = Math.abs(id - highid);
        int lowdiff = Math.abs(id - lowid);
    
        if(highdiff < lowdiff) return high;
        return low;
    
    }