ClassNameUtils { static String replaceTypeParameter(final String str, final Map<String, String> replaceMap) { final int idx = str.indexOf('<'); StringBuilder all = new StringBuilder(64); if (idx >= 0) { String pre = str.substring(0, idx + 1); all.append(pre); String genericsStr = str.substring(idx + 1, str.length() - 1); int indent = 0; StringBuilder sb = new StringBuilder(16); boolean wild = false; int len = genericsStr.length(); for (int i = 0; i < len; i++) { char c = genericsStr.charAt(i); switch (c) { case '?': if (indent == 0) { sb.append(c); wild = true; } else { sb.append(c); } continue; case '<': sb.append(c); indent++; continue; case '>': indent--; sb.append(c); continue; case ' ': if (wild) { sb.append(c); } continue; case ',': if (indent == 0 && sb.length() > 0) { wild = false; final String gen = sb.toString(); replaceTypeStr(replaceMap, all, gen); all.append(", "); sb.setLength(0); } else { sb.append(c); sb.append(' '); } continue; default: sb.append(c); } } if (sb.length() > 0) { final String gen = sb.toString(); replaceTypeStr(replaceMap, all, gen); } all.append('>'); return all.toString(); } return str; } private  ClassNameUtils(); static boolean isPrimitive(final String className); static boolean isArray(final String name); static String replaceFromMap(final String string, final Map<String, String> replacements); static String replaceDot2FileSep(final String string); static String replaceSlash(String string); static String getParentClass(final String name); static String replaceInnerMark(final String string); static String replaceDotToInnerMark(String string, boolean last); static String removeTypeMark(final String val); static Optional<String> toInnerClassName(final String name); static boolean hasPackage(String name); static String getSimpleName(final String fqcn); static String getPackage(final String fqcn); static Optional<String> getTypeVariable(final String val); static String removeTypeParameter(String name); static String removeTypeAndArray(String name); static List<String> parseTypeParameter(final String str); static String removeCapture(final String name); static String removeCaptureAndWildCard(final String name); static String getAllSimpleName(final String name); static String removeWildcard(final String name); static boolean compareArgumentType(
      List<String> arguments, List<String> parameters, boolean hasVarargs); static boolean isAnonymousClass(final String name); static void replaceDescriptorsType(
      final String nameWithTP, final List<MemberDescriptor> members); static String getClassName(final String s); static final String OBJECT_CLASS; static final String OBJECT; static final String CLASS_TYPE_VARIABLE_MARK; static final String FORMAL_TYPE_VARIABLE_MARK; static final String INNER_MARK; static final String CAPTURE_OF; static final String ARRAY; }
@Test public void replaceTypeParameter1() throws Exception { String name = "java.util.function.Function<? super String, ? extends R>"; Map<String, String> map = new HashMap<>(); map.putIfAbsent("R", "java.util.stream.Stream<String>"); final String s = ClassNameUtils.replaceTypeParameter(name, map); assertEquals( "java.util.function.Function<? super String, ? extends java.util.stream.Stream<String>>", s); }
@Test public void replaceTypeParameter2() throws Exception { String name = "java.util.function.Function<? super T, ? extends Stream<? extends R>>"; Map<String, String> map = new HashMap<>(); map.putIfAbsent("T", "java.lang.Integer"); map.putIfAbsent("R", "java.lang.String"); final String s = ClassNameUtils.replaceTypeParameter(name, map); assertEquals( "java.util.function.Function<? super java.lang.Integer, ? extends Stream<? extends java.lang.String>>", s); }
@Test public void replaceTypeParameter3() throws Exception { String name = "java.util.function.Function<? super T, ? extends Stream<? extends R>>"; Map<String, String> map = new HashMap<>(); map.putIfAbsent("T", "java.lang.Integer"); final String s = ClassNameUtils.replaceTypeParameter(name, map); assertEquals( "java.util.function.Function<? super java.lang.Integer, ? extends Stream<? extends R>>", s); }