|
11 | 11 | import java.util.Deque; |
12 | 12 | import java.util.HashMap; |
13 | 13 | import java.util.Iterator; |
14 | | -import java.util.LinkedHashMap; |
15 | 14 | import java.util.List; |
16 | 15 | import java.util.Map; |
17 | 16 | import java.util.Objects; |
@@ -622,7 +621,8 @@ public abstract class AbstractCodeWriter<T extends AbstractCodeWriter<T>> { |
622 | 621 | private boolean trailingNewline = true; |
623 | 622 | private int trimBlankLines = -1; |
624 | 623 | private boolean enableStackTraceComments; |
625 | | - private final Map<String, Supplier<String>> deferredValues = new LinkedHashMap<>(); |
| 624 | + private final List<String> deferredPlaceholders = new ArrayList<>(); |
| 625 | + private final List<Supplier<String>> deferredSuppliers = new ArrayList<>(); |
626 | 626 | private int deferredCounter = 0; |
627 | 627 |
|
628 | 628 | /** |
@@ -789,30 +789,24 @@ public String toString() { |
789 | 789 | String result = currentState.toString(); |
790 | 790 |
|
791 | 791 | // Resolve any deferred values. |
792 | | - if (!deferredValues.isEmpty()) { |
| 792 | + if (!deferredPlaceholders.isEmpty()) { |
793 | 793 | // Find all sentinel positions, then resolve in a single linear pass. |
794 | 794 | List<int[]> positions = new ArrayList<>(); |
795 | | - int idx = 0; |
796 | | - for (Map.Entry<String, Supplier<String>> entry : deferredValues.entrySet()) { |
797 | | - String key = entry.getKey(); |
| 795 | + for (int i = 0; i < deferredPlaceholders.size(); i++) { |
| 796 | + String key = deferredPlaceholders.get(i); |
798 | 797 | int fromIndex = 0; |
799 | 798 | while ((fromIndex = result.indexOf(key, fromIndex)) != -1) { |
800 | | - // Store [position, index-into-entries-list, key-length] |
801 | | - positions.add(new int[]{fromIndex, idx, key.length()}); |
| 799 | + positions.add(new int[]{fromIndex, i, key.length()}); |
802 | 800 | fromIndex += key.length(); |
803 | 801 | } |
804 | | - idx++; |
805 | 802 | } |
806 | 803 | if (!positions.isEmpty()) { |
807 | 804 | positions.sort((a, b) -> Integer.compare(a[0], b[0])); |
808 | | - // Build list of suppliers indexed by insertion order for O(1) lookup. |
809 | | - @SuppressWarnings("unchecked") |
810 | | - Supplier<String>[] suppliers = deferredValues.values().toArray(new Supplier[0]); |
811 | 805 | StringBuilder resolved = new StringBuilder(result.length()); |
812 | 806 | int pos = 0; |
813 | 807 | for (int[] entry : positions) { |
814 | 808 | resolved.append(result, pos, entry[0]); |
815 | | - resolved.append(suppliers[entry[1]].get()); |
| 809 | + resolved.append(deferredSuppliers.get(entry[1]).get()); |
816 | 810 | pos = entry[0] + entry[2]; |
817 | 811 | } |
818 | 812 | resolved.append(result, pos, result.length()); |
@@ -1810,7 +1804,8 @@ public final String format(Object content, Object... args) { |
1810 | 1804 | */ |
1811 | 1805 | protected final String defer(Supplier<String> supplier) { |
1812 | 1806 | String id = "\u0000\u0000" + (deferredCounter++) + "\u0000\u0000"; |
1813 | | - deferredValues.put(id, supplier); |
| 1807 | + deferredPlaceholders.add(id); |
| 1808 | + deferredSuppliers.add(supplier); |
1814 | 1809 | return id; |
1815 | 1810 | } |
1816 | 1811 |
|
|
0 commit comments