Java 没有像 C# 那样使用“推送”逻辑迭代值的功能yield return
does.
Java仅支持“拉”逻辑,使用Enumeration https://docs.oracle.com/javase/8/docs/api/java/util/Enumeration.html, Iterator https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html, or Spliterator https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html (what Stream https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html uses).
如果你有记忆,你当然可以将所有组合“推入”一个ArrayList
,然后从那里“拉”值。转换yield return
逻辑成list.add()
调用很容易,所以我假设你不想要这样。
Java 相当于IEnumerable
is Iterable https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html,所以你需要一个Iterator
执行。
下面的代码将做到这一点。它是基于我对另一个问题的回答 https://stackoverflow.com/a/46374733/5221149,所以请阅读该答案以获取整体逻辑的解释,但基本上,您的示例就像在这个锯齿状数组中生成字符组合:
{{'A', 'H'}, {'B'}, {'C'}, {'1', 'I'}, {'2'}, {'3', 'B'}}
在下面的代码中,锯齿状数组是textChars
数组,但不是使用char[]
它使用一个String
,因为一个String
实际上只是只读char[]
.
public static Iterable<String> combinations(String text, String... replacements) {
Map<Character, String> repl = new HashMap<>();
for (String r : replacements)
if (repl.putIfAbsent(r.charAt(0), r) != null)
throw new IllegalArgumentException("Duplicate replacement: [" + repl.get(r.charAt(0)) + "] vs [" + r + "]");
String[] textChars = new String[text.length()];
long count = 1;
for (int i = 0; i < textChars.length; i++) {
textChars[i] = repl.getOrDefault(text.charAt(i), text.substring(i, i+1));
count = Math.multiplyExact(count, textChars[i].length());
}
long comboCount = count;
return () -> new Iterator<>() {
private long combo = 0;
@Override
public boolean hasNext() {
return (this.combo < comboCount);
}
@Override
public String next() {
if (this.combo >= comboCount)
throw new NoSuchElementException();
long c = this.combo++;
char[] buf = new char[textChars.length];
for (int i = buf.length - 1; i >= 0; i--) {
buf[i] = textChars[i].charAt((int) (c % textChars[i].length()));
c /= textChars[i].length();
}
return new String(buf);
}
};
}
Test
combinations("ABC123", "1I", "3B", "AH", "O0", "0O").forEach(System.out::println);
Output
ABC123
ABC12B
ABCI23
ABCI2B
HBC123
HBC12B
HBCI23
HBCI2B