我有一个有效的C#和弦移调功能。我尝试将其重写为Java,但是由于某种原因,它似乎无效。也许Java正则表达式不支持lambda吗?
private String transposeChord(String ChordRegel, Integer amount)
{
String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
java.util.Map<String, String> normalizeMap = new java.util.HashMap<>();
normalizeMap.put("Cb", "B");
normalizeMap.put("Db", "C#");
normalizeMap.put("Eb", "D#");
normalizeMap.put("Fb", "E");
normalizeMap.put("Gb", "F#");
normalizeMap.put("Ab", "G#");
normalizeMap.put("Bb", "A#");
normalizeMap.put("E#", "F");
normalizeMap.put("B#", "C");
Pattern r = Pattern.compile("[CDEFGAB](b|#)?");
Matcher match = r.matcher(ChordRegel);
return ChordRegel.replaceAll("[CDEFGAB](b|#)?", match =>
int i = (java.util.Arrays.asList(scale).indexOf(normalizeMap.containsKey(match.toString()) ? normalizeMap.get(match.toString()) : match.toString()) + amount) % scale.length;
return scale[ i < 0 ? i + scale.length : i ];)
) ;
}
这是有效的C#版本:
private string transposeChord(string ChordRegel, int amount)
{
string[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
string[] scale2 = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };
var normalizeMap = new Dictionary<string, string>() { { "Cb", "B" }, { "Db", "C#" }, { "Eb", "D#" }, { "Fb", "E" }, { "Gb", "F#" }, { "Ab", "G#" }, { "Bb", "A#" }, { "E#", "F" }, { "B#", "C" } };
var normalizeMap2 = new Dictionary<string, string>() { { "C#", "Db" }, { "D#", "Eb" }, { "E#", "F" }, { "F#", "Gb" }, { "G#", "Ab" }, { "A#", "Bb" }, { "B#", "C" }, { "Fb", "E" } };
return new Regex("[CDEFGAB](b|#)?").Replace(ChordRegel, match =>
{
int i = 0; string NewKey = "";
if (Mollen.Checked == true)
{
i = (Array.IndexOf(scale2, normalizeMap2.ContainsKey(match.Value) ? normalizeMap2[match.Value] : match.Value) + amount) % scale2.Length;
NewKey = scale2[i < 0 ? i + scale2.Length : i];
}
else
{
i = (Array.IndexOf(scale, normalizeMap.ContainsKey(match.Value) ? normalizeMap[match.Value] : match.Value) + amount) % scale.Length;
NewKey = scale[i < 0 ? i + scale.Length : i];
}
return NewKey;
});
}
答案 0 :(得分:3)
为了获得最佳性能,我会在Java 11中这样做(请参阅最后的Java 8版本):
private static final String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
private static final Map<String, Integer> scaleIndex = new HashMap<>();
static {
Map<String, String> normalizeMap = Map.of("Cb", "B", "Db", "C#", "Eb", "D#", "Fb", "E", "Gb", "F#", "Ab", "G#", "Bb", "A#", "E#", "F", "B#", "C");
for (int i = 0; i < scale.length; i++)
scaleIndex.put(scale[i], i);
for (String s : normalizeMap.keySet())
scaleIndex.put(s, scaleIndex.get(normalizeMap.get(s)));
}
private static String transposeChord(String chordRegel, int amount) {
int normalizedAmount = (amount % scale.length + scale.length) % scale.length;
return Pattern.compile("[CDEFGAB][b#]?").matcher(chordRegel).replaceAll(r ->
scale[(scaleIndex.get(r.group()) + normalizedAmount) % scale.length]);
}
scaleIndex
映射的构建仅完成一次,而normalizedAmount
始终为0-11。
测试
for (int i = -12; i <= 12; i++)
System.out.printf("%3d: %s%n", i, transposeChord("CbCC#", i));
输出
-12: BCC#
-11: CC#D
-10: C#DD#
-9: DD#E
-8: D#EF
-7: EFF#
-6: FF#G
-5: F#GG#
-4: GG#A
-3: G#AA#
-2: AA#B
-1: A#BC
0: BCC#
1: CC#D
2: C#DD#
3: DD#E
4: D#EF
5: EFF#
6: FF#G
7: F#GG#
8: GG#A
9: G#AA#
10: AA#B
11: A#BC
12: BCC#
更新: Java 8版本,未使用lambda:
private static final String[] scale = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
private static final Map<String, Integer> scaleIndex = new HashMap<>();
static {
String[] normalize = { "Cb", "B", "Db", "C#", "Eb", "D#", "Fb", "E", "Gb", "F#", "Ab", "G#", "Bb", "A#", "E#", "F", "B#", "C" };
for (int i = 0; i < scale.length; i++)
scaleIndex.put(scale[i], i);
for (int i = 0; i < normalize.length; i += 2)
scaleIndex.put(normalize[i], scaleIndex.get(normalize[i + 1]));
}
private static String transposeChord(String chordRegel, int amount) {
int normalizedAmount = (amount % scale.length + scale.length) % scale.length;
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("[CDEFGAB][b#]?").matcher(chordRegel);
while (m.find())
m.appendReplacement(buf, scale[(scaleIndex.get(m.group()) + normalizedAmount) % scale.length]);
return m.appendTail(buf).toString();
}