Java 在另一个列表中查找最接近的值

Java 在另一个列表中查找最接近的值,java,Java,如果问题不清楚,请告诉我。我可以提供更多信息。我在ArrayList中有以下音符 ArrayList<String> notesList = new ArrayList<>(); notesList.add("A"); //0 notesList.add("A#"); //1 notesList.add("B"); //2 notesList.add("C"); //3 notesList.add("C#"); //4 notesList

如果问题不清楚,请告诉我。我可以提供更多信息。我在ArrayList中有以下音符

ArrayList<String> notesList = new ArrayList<>();
notesList.add("A");    //0
notesList.add("A#");    //1
notesList.add("B");     //2
notesList.add("C");     //3
notesList.add("C#");    //4
notesList.add("D");     //5
notesList.add("D#");    //6
notesList.add("E");     //7
notesList.add("F");     //8
notesList.add("F#");    //9
notesList.add("G");     //10
notesList.add("G#");    //11
我需要通过升序列表和降序列表生成模式,反之亦然。 例如:

D、 E(从升序列表),E,C#(从降序列表)C,D,E,F#

(上升)、F、E、C#、A(下降)

F E C#(下降),D,E(上升)

这样做是有条件的。当我想在升序模式的末尾连接降序模式时,我需要找到下一个等于或低于上一个升序音符的音符,但在降序列表中

例:如果F#是升序模式中的最后一个音符,那么F应该是降序模式中的第一个音符。如果E是上升模式中的最后一个音符,那么E也是下降模式中的第一个音符,因为E在上升和下降模式中都存在。类似地,当我在降序模式的末尾生成升序模式时,我需要找到下一个音符等于或高于上一个降序音符

我想不出怎么做。 我尝试的一种方法是,根据
notesList
查找升序和降序索引,然后考虑映射,然后使用
map.higherKey
map.lowerKey
等方法。但无法继续,因为我无法真正映射它们。

enum Note{
enum Note {
    C, C_, D, D_, E, F, F_, G, G_, A, A_, B;

    public Note above() {
        return ordinal() != values().length - 1
                ? Note.values()[ordinal() + 1]
                : Note.values()[0];
    }

    public Note below() {
        return ordinal() > 0
                ? Note.values()[ordinal() - 1]
                : Note.values()[Note.values().length - 1];
    }
}

interface Scale {
    ListIterator<Note> joinAfter(Note note);
}

Scale ascending = new Scale() {
    List<Note> notes = asList(C, D, E, F_, G);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.above()));
    }
};

Scale descending = new Scale() {
    List<Note> notes = asList(A, C_, E, F, G, G_);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.below()));
    }
};
C、 C_,D,D_,E,F,F_,G,G_,A,A_,B; 以上公开说明(){ 返回序号()!=值()。长度-1 ?注释.值()[序数()+1] :Note.values()[0]; } 以下公开说明(){ 返回序号()>0 ?注.值()[序数()-1] :Note.values()[Note.values().length-1]; } } 界面比例{ ListIterator joinAfter(注); } 上升比例=新比例(){ 列表注释=asList(C、D、E、F_ug); @凌驾 公共列表迭代器joinAfter(注意){ returnnotes.listIterator(notes.contains(note)?notes.indexOf(note):notes.indexOf(note.over()); } }; 比例下降=新比例(){ 列表注释=asList(A、C、E、F、G、G); @凌驾 公共列表迭代器joinAfter(注意){ returnnotes.listIterator(notes.contains(note)?notes.indexOf(note):notes.indexOf(note.below()); } };
我建议您添加自己的
迭代器
包装器,它将在DerningScale中调用previous for next(如果您出于某种原因不想在此处反转注释),更重要的是,它允许您无限循环缩放


如果这只是一个学校的广告,你最好坚持数字,在你需要打印出来之前不要弄乱字符串列表。顺便说一句,这里的阵列将是一个更好的选择。

一种可能的方法。对于升序和降序,创建与notesList大小相同的整数(或布尔数)数组。值1表示注释在列表中,值0表示不在列表中。基本上,您可以使用递增/递减结构来索引到noteList中。比如:

int index = 3;
if (1 == acending[index]) {
    note = noteList[index];
}
创建方法在升序和降序列表中上下移动索引,以查找下一个有效(非零)条目。从升序切换到降序时,在降序列表上使用相同的索引。如果你的笔记是有效的,那么就使用它,而不是,向下搜索下一个有效的笔记


很多变化都是可能的。您可以创建名为AscendingScale和DescendingScale的对象,用于封装list和move方法

你能展示一下你的尝试吗?编码还没有完成。但我的计划是:首先,我们知道最后一个音符,从那里连接到另一个列表。通过这个位置,我可以知道notesList中的位置(例如:notesList中Notee的位置=7)。现在查看其他列表中是否存在此项。如果不是,则递增或递减索引(取决于递增类型或递减类型),并查看是否找到匹配项。我认为可能有更好/更简单的方法使用地图,这样可以减少编码。
enum Note {
    C, C_, D, D_, E, F, F_, G, G_, A, A_, B;

    public Note above() {
        return ordinal() != values().length - 1
                ? Note.values()[ordinal() + 1]
                : Note.values()[0];
    }

    public Note below() {
        return ordinal() > 0
                ? Note.values()[ordinal() - 1]
                : Note.values()[Note.values().length - 1];
    }
}

interface Scale {
    ListIterator<Note> joinAfter(Note note);
}

Scale ascending = new Scale() {
    List<Note> notes = asList(C, D, E, F_, G);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.above()));
    }
};

Scale descending = new Scale() {
    List<Note> notes = asList(A, C_, E, F, G, G_);

    @Override
    public ListIterator<Note> joinAfter(Note note) {
        return notes.listIterator(notes.contains(note)? notes.indexOf(note) : notes.indexOf(note.below()));
    }
};
int index = 3;
if (1 == acending[index]) {
    note = noteList[index];
}