Java Sind "Multi"-Streams mit Indexvariable in Java möglich?

Tobias0

Banned
Registriert
Aug. 2025
Beiträge
117
Lässt sich die folgende Methode getTemplate vielleicht vereinfachen, sodass ich das AtomicInteger ai, was nur ein Workaround darstellt, loswerde?

Java:
  private static final HashMap<String, String> templates = new HashMap<>();

  private static String getTemplate(String path, String... args) throws IOException {
    if (!templates.containsKey(path)) {
      try (InputStream templateStream = Main.class.getResourceAsStream(path)) {
        assert templateStream != null;
        templates.put(path, new String(templateStream.readAllBytes(), StandardCharsets.UTF_8));
      }
    }
    AtomicInteger ai = new AtomicInteger(0); // Dies ist ein Workaround
    return StringSubstitutor.replace(
        templates.get(path),
        Arrays.stream(args)
            .reduce(
                new HashMap<>(),
                (map, element) -> {
                  map.put(ai.getAndIncrement() + "", element);
                  return map;
                },
                (map1, map2) -> {
                  map1.putAll(map2);
                  return map1;
                }),
        "{{",
        "}}");
  }

In der Map soll halt hinterher stehen: (0,args[0]), (1,args[1]), usw.

Edit:

Ach, ich habe wohl einfach zu kompliziert gedacht:

Java:
  private static String getTemplate(String path, String... args) throws IOException {
    if (!templates.containsKey(path)) {
      try (InputStream templateStream = Main.class.getResourceAsStream(path)) {
        assert templateStream != null;
        templates.put(path, new String(templateStream.readAllBytes(), StandardCharsets.UTF_8));
      }
    }
    return StringSubstitutor.replace(
        templates.get(path),
        IntStream.range(0, args.length)
            .boxed()
            .reduce(
                new HashMap<>(),
                (map, i) -> {
                  map.put(i + "", args[i]);
                  return map;
                },
                (map1, map2) -> {
                  map1.putAll(map2);
                  return map1;
                }),
        "{{",
        "}}");
  }

Danke, dennoch.
 
Zuletzt bearbeitet:
Eine klassische for Schleife mit Indexvariable über args.length wäre wohl ausreichend mit Map#put.
Stream#reduce ist in dem Fall nicht wirklich nötig.

Maps zu instanzieren ist zudem nicht sehr effizient.
 
@slumpie Nein, du hast das Problem noch nicht verstanden.

Ein:

Java:
    return StringSubstitutor.replace(
        templates.get(path),
        IntStream.range(0, args.length)
            .boxed()
            .collect(
                Collectors.toMap(
                    i -> i + "", // key is the index as a string
                    i -> args[i] // value is the corresponding argument
                    )),
        "{{",
        "}}");

ist völlig richtig und auch schnell. "Combine"- oder Zip-Streams gibt es in Java leider nicht.
Ergänzung ()

Siehe auch hier.
Ergänzung ()

Das Guava von Google hätte allerdings so eine Funktion:

 
Zuletzt bearbeitet:
1. Waren das jetzt drei verschiedene Varianten deinerseits.

2. Was soll ich falsch verstanden haben?
Java:
private static String getTemplate(String path, String... args)
{
  final Map<String, String> map = new HashMap<>(args.length);
  for (int i = 0; i < args.length; i++)
  {
    map.put(i + "", args[i]);
  }
  return StringSubstitutor.replace(templates.get(path), map, "{{", "}}");
}
 
  • Gefällt mir
Reaktionen: Tornhoof
Was soll falsch sein?

Test 1
Template: The {{0}} jumped over the {{1}} {{2}}.
Args: [cat, fence, twice]
Yours: The cat jumped over the fence twice.
Mine: The cat jumped over the fence twice.
Same: true

Test 2
Template: The {{0}} jumped over the {{1}} {{2}}.
Args:
Yours: The {{0}} jumped over the {{1}} {{2}}.
Mine: The {{0}} jumped over the {{1}} {{2}}.
Same: true
 
Hast du dir mal angesehen was bei Streams und Collectors so alles gemacht wird und du machst dir wirklich Sorgen wegen einer lokalen Variable?
 
  • Gefällt mir
Reaktionen: Tornhoof
Ob ich mir nun Sorgen mache oder nicht, ist irrelevant. Es ist ein Anti-Pattern, auch wenn es keinen semantischen Unterschied gibt, weil es mittlerweile Streams gibt.

Aber, to be fair, hätte ich das früher (vor der Einführung von Streams usw.) auch so geschrieben.

Es geht hier nur um die Programmiertechnik, also Clean-Code. Der Byte-Code kann gleich sein, aber das ist nicht das, worauf es hinterher ankommt ... Code muss lesbar sein usw.

Du würdest übersetzte C-Programme ja auch nicht anhand der Binärcodes beurteilen wollen.
 
Das erinnert mich an
1000007612.jpg
Ergänzung ()

Tobias0 schrieb:
Es geht hier nur um die Programmiertechnik, also Clean-Code. Der Byte-Code kann gleich sein, aber das ist nicht das, worauf es hinterher ankommt ... Code muss lesbar sein usw.
Wenn du meinst, dass dein Code lesbarer ist als der von @slumpie , dann haben wir echt ein unterschiedliches Verständnis von lesbar.

Ich mach schon seit Jahren kein Java mehr, aber bei deinem Code mußte ich schon länger darauf starren um zu kapieren dass da was ähnliches rauskommen soll wie beim Code von @slumpie
 
  • Gefällt mir
Reaktionen: Bagbag, nutrix und Tobias0
Zurück
Oben