From: "Enrico Weigelt, metux IT consult" <enrico.weig...@gr13.net>

We have several places where lists are walked and names/strings derived
from the list elements are collected in a comma-separated list (string).

Instead of using expensive stream operations (with lots of callbacks),
just loop over the list and collect in a specialized string buffer.
---
 src/net/sf/freecol/FreeCol.java                    |  7 ++-
 src/net/sf/freecol/client/gui/ModifierFormat.java  | 24 +++++---
 .../gui/panel/colopedia/ResourcesDetailPanel.java  | 12 ++--
 .../sf/freecol/common/debug/FreeColDebugger.java   | 11 +++-
 src/net/sf/freecol/common/model/Specification.java | 16 ++++--
 .../sf/freecol/common/networking/LoginMessage.java | 21 +++----
 src/net/sf/freecol/common/util/Introspector.java   |  7 ++-
 src/net/sf/freecol/common/util/StrCat.java         | 67 ++++++++++++++++++++++
 8 files changed, 128 insertions(+), 37 deletions(-)
 create mode 100644 src/net/sf/freecol/common/util/StrCat.java

diff --git a/src/net/sf/freecol/FreeCol.java b/src/net/sf/freecol/FreeCol.java
index bc69506005c..b746b8ccd9a 100644
--- a/src/net/sf/freecol/FreeCol.java
+++ b/src/net/sf/freecol/FreeCol.java
@@ -57,6 +57,7 @@ import net.sf.freecol.common.model.StringTemplate;
 import net.sf.freecol.common.option.OptionGroup;
 import static net.sf.freecol.common.util.CollectionUtils.*;
 import net.sf.freecol.common.util.LogBuilder;
+import net.sf.freecol.common.util.StrCat;
 import net.sf.freecol.server.FreeColServer;
 
 import org.apache.commons.cli.CommandLine;
@@ -995,8 +996,10 @@ public final class FreeCol {
      * @return A list of advantage types.
      */
     private static String getValidAdvantages() {
-        return transform(Advantages.values(), alwaysTrue(),
-                         a -> Messages.getName(a), Collectors.joining(","));
+        StrCat cat = new StrCat(",");
+        for (Advantages walk : Advantages.values())
+            cat.add(Messages.getName(walk));
+        return cat.toString();
     }
 
     /**
diff --git a/src/net/sf/freecol/client/gui/ModifierFormat.java 
b/src/net/sf/freecol/client/gui/ModifierFormat.java
index c15c78808dd..60e20895276 100644
--- a/src/net/sf/freecol/client/gui/ModifierFormat.java
+++ b/src/net/sf/freecol/client/gui/ModifierFormat.java
@@ -20,8 +20,6 @@
 package net.sf.freecol.client.gui;
 
 import java.text.DecimalFormat;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import javax.swing.JLabel;
 
@@ -36,6 +34,7 @@ import net.sf.freecol.common.model.Named;
 import net.sf.freecol.common.model.Scope;
 import net.sf.freecol.common.model.Turn;
 import static net.sf.freecol.common.util.CollectionUtils.*;
+import net.sf.freecol.common.util.StrCat;
 
 
 public class ModifierFormat {
@@ -115,14 +114,23 @@ public class ModifierFormat {
     }
 
     public static String getFeatureAsString(Feature feature) {
-        return Messages.getName(feature) + ":"
-            + ((!feature.hasScope()) ? ""
-                : transform(feature.getScopes(), isNotNull(),
-                            Scope::getFeatureString, Collectors.joining(",")));
+        if (!feature.hasScope())
+            return Messages.getName(feature);
+
+        StrCat cat = new StrCat(",");
+        cat.append(Messages.getName(feature)).append(":");
+
+        for (Scope scope : feature.getScopes())
+            if (scope != null)
+                cat.add(scope.getFeatureString());
+
+        return cat.toString();
     }
 
     public static String getModifierAsString(Modifier modifier) {
-        return transform(getModifierStrings(modifier), isNotNull(),
-                         Function.identity(), Collectors.joining());
+        StringBuilder sb = new StringBuilder();
+        for (String s : getModifierStrings(modifier))
+            if (s != null) sb.append(s);
+        return sb.toString();
     }
 }
diff --git 
a/src/net/sf/freecol/client/gui/panel/colopedia/ResourcesDetailPanel.java 
b/src/net/sf/freecol/client/gui/panel/colopedia/ResourcesDetailPanel.java
index 1dee2d4e3fd..eea89593a5d 100644
--- a/src/net/sf/freecol/client/gui/panel/colopedia/ResourcesDetailPanel.java
+++ b/src/net/sf/freecol/client/gui/panel/colopedia/ResourcesDetailPanel.java
@@ -20,7 +20,6 @@
 package net.sf.freecol.client.gui.panel.colopedia;
 
 import java.util.List;
-import java.util.stream.Collectors;
 
 import javax.swing.JButton;
 import javax.swing.JLabel;
@@ -39,6 +38,7 @@ import net.sf.freecol.common.model.Modifier;
 import net.sf.freecol.common.model.ResourceType;
 import net.sf.freecol.common.model.Scope;
 import net.sf.freecol.common.model.Specification;
+import net.sf.freecol.common.util.StrCat;
 import static net.sf.freecol.common.util.CollectionUtils.*;
 
 
@@ -93,11 +93,11 @@ public class ResourcesDetailPanel
         for (Modifier modifier : mods) {
             String text = ModifierFormat.getModifierAsString(modifier);
             if (modifier.hasScope()) {
-                String scopes = transform(modifier.getScopes(),
-                                          isNotNull(Scope::getType),
-                                          s -> 
Messages.getName(spec.findType(s.getType())),
-                                          Collectors.joining(", "));
-                if (!scopes.isEmpty()) text += " (" + scopes + ")";
+                StrCat cat = new StrCat(", ");
+                for (Scope s : modifier.getScopes())
+                    cat.add(Messages.getName(spec.findType(s.getType())));
+                if (!cat.isEmpty())
+                    text += " (" + cat.toString() + ")";
             }
 
             GoodsType goodsType = spec.getGoodsType(modifier.getId());
diff --git a/src/net/sf/freecol/common/debug/FreeColDebugger.java 
b/src/net/sf/freecol/common/debug/FreeColDebugger.java
index b5bfbb4192c..4299a513e8d 100644
--- a/src/net/sf/freecol/common/debug/FreeColDebugger.java
+++ b/src/net/sf/freecol/common/debug/FreeColDebugger.java
@@ -28,13 +28,13 @@ import java.io.PrintStream;
 
 import java.util.Locale;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 
 import net.sf.freecol.client.FreeColClient;
 import net.sf.freecol.common.io.FreeColDirectories;
 import net.sf.freecol.common.model.Player;
 import static net.sf.freecol.common.util.CollectionUtils.*;
 import net.sf.freecol.common.util.LogBuilder;
+import net.sf.freecol.common.util.StrCat;
 import net.sf.freecol.server.FreeColServer;
 
 
@@ -134,8 +134,13 @@ public class FreeColDebugger {
      * @return A string containing the modes as csv.
      */
     public static String getDebugModes() {
-        return transform(DebugMode.values(), m -> isInDebugMode(m),
-                         DebugMode::toString, Collectors.joining(","));
+        StrCat cat = new StrCat(",");
+
+        for (DebugMode m : DebugMode.values())
+            if (isInDebugMode(m))
+                cat.add(m.toString());
+
+        return cat.toString();
     }
 
     /**
diff --git a/src/net/sf/freecol/common/model/Specification.java 
b/src/net/sf/freecol/common/model/Specification.java
index 58e698ba9da..9a11275f1be 100644
--- a/src/net/sf/freecol/common/model/Specification.java
+++ b/src/net/sf/freecol/common/model/Specification.java
@@ -34,7 +34,6 @@ import java.util.function.Predicate;
 import java.util.function.Function;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import javax.xml.stream.XMLStreamException;
@@ -59,6 +58,7 @@ import net.sf.freecol.common.option.StringOption;
 import net.sf.freecol.common.option.TextOption;
 import net.sf.freecol.common.option.UnitListOption;
 import static net.sf.freecol.common.util.CollectionUtils.*;
+import net.sf.freecol.common.util.StrCat;
 
 
 /**
@@ -2043,10 +2043,13 @@ public final class Specification {
             return;
         }
 
+        StrCat cat = new StrCat(" ");
+        for (Role r : getRoles())
+            cat.add(r.getId());
+
         logger.info("Loading role backward compatibility fragment: "
             + ROLES_COMPAT_FILE_NAME + " with roles: "
-            + transform(getRoles(), alwaysTrue(), Role::getId,
-                        Collectors.joining(" ")));
+            + cat.toString());
     }
     // end @compat 0.10.x
 
@@ -3035,10 +3038,13 @@ public final class Specification {
                 return;
             }
 
+            StrCat cat = new StrCat(" ");
+            for (UnitChangeType uct : getUnitChangeTypeList())
+                cat.add(uct.getId());
+
             logger.info("Loading unit-change-types backward compatibility 
fragment: "
                 + UNIT_CHANGE_TYPES_COMPAT_FILE_NAME + " with changes: "
-                + transform(getUnitChangeTypeList(), alwaysTrue(),
-                            UnitChangeType::getId, Collectors.joining(" ")));
+                + cat.toString());
         }
     }
 
diff --git a/src/net/sf/freecol/common/networking/LoginMessage.java 
b/src/net/sf/freecol/common/networking/LoginMessage.java
index f7a1be4b0ff..7b1a9300688 100644
--- a/src/net/sf/freecol/common/networking/LoginMessage.java
+++ b/src/net/sf/freecol/common/networking/LoginMessage.java
@@ -19,8 +19,6 @@
 
 package net.sf.freecol.common.networking;
 
-import java.util.stream.Collectors;
-
 import net.sf.freecol.FreeCol;
 import net.sf.freecol.common.model.Game;
 import net.sf.freecol.common.model.Nation;
@@ -29,6 +27,7 @@ import net.sf.freecol.common.model.StringTemplate;
 import net.sf.freecol.common.networking.AddPlayerMessage;
 import net.sf.freecol.common.networking.ErrorMessage;
 import net.sf.freecol.common.networking.SetAIMessage;
+import net.sf.freecol.common.util.StrCat;
 import static net.sf.freecol.common.util.CollectionUtils.*;
 import net.sf.freecol.server.FreeColServer;
 import net.sf.freecol.server.FreeColServer.ServerState;
@@ -229,13 +228,14 @@ public class LoginMessage extends DOMMessage {
             game = freeColServer.getGame(); // Restoring from existing game.
             present = getPlayerByName(game);
             if (present == null) {
+                StrCat cat = new StrCat(", ");
+                for (Player p : game.getLiveEuropeanPlayers())
+                    cat.add(p.getName());
+
                 return ChangeSet.clientError((ServerPlayer)null, StringTemplate
                     .template("server.userNameNotPresent")
                     .addName("%name%", userName)
-                    .addName("%names%",
-                        transform(game.getLiveEuropeanPlayers(),
-                                  alwaysTrue(), Player::getName,
-                            Collectors.joining(", "))));
+                    .addName("%names%", cat.toString()));
             } else if (present.isConnected()) {
                 // Another player already connected on the name
                 return ChangeSet.clientError((ServerPlayer)null, StringTemplate
@@ -265,13 +265,14 @@ public class LoginMessage extends DOMMessage {
             game = freeColServer.getGame(); // Restoring from existing game.
             present = getPlayerByName(game);
             if (present == null) {
+                StrCat cat = new StrCat(", ");
+                for (Player p : game.getLiveEuropeanPlayers())
+                    cat.add(p.getName());
+
                 return ChangeSet.clientError((ServerPlayer)null, StringTemplate
                     .template("server.userNameNotPresent")
                     .addName("%name%", userName)
-                    .addName("%names%",
-                        transform(game.getLiveEuropeanPlayers(),
-                                  alwaysTrue(), Player::getName,
-                            Collectors.joining(", "))));
+                    .addName("%names%", cat.toString()));
             } else if (present.isAI()) { // Allow to join over AI player
                 present.setAI(false);
                 freeColServer.sendToAll(new SetAIMessage(present, false),
diff --git a/src/net/sf/freecol/common/util/Introspector.java 
b/src/net/sf/freecol/common/util/Introspector.java
index 0e6e5ae5094..0edc686b534 100644
--- a/src/net/sf/freecol/common/util/Introspector.java
+++ b/src/net/sf/freecol/common/util/Introspector.java
@@ -23,7 +23,6 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.util.stream.Collectors;
 
 import static net.sf.freecol.common.util.CollectionUtils.*;
 import static net.sf.freecol.common.util.StringUtils.*;
@@ -347,10 +346,12 @@ public class Introspector {
         try {
             constructor = messageClass.getDeclaredConstructor(types);
         } catch (NoSuchMethodException | SecurityException ex) {
+            StrCat cat = new StrCat(",");
+            for (Class cls : types)
+                cat.add(cls.getName());
             throw new IntrospectorException("Unable to find constructor "
                 + lastPart(tag, ".") + "("
-                + transform(types, alwaysTrue(), Class::getName,
-                            Collectors.joining(","))
+                + cat.toString()
                 + ")", ex);
         }
         T instance;
diff --git a/src/net/sf/freecol/common/util/StrCat.java 
b/src/net/sf/freecol/common/util/StrCat.java
new file mode 100644
index 00000000000..eb7b64b6d1e
--- /dev/null
+++ b/src/net/sf/freecol/common/util/StrCat.java
@@ -0,0 +1,67 @@
+/**
+ *  Copyright (C) 2002-2016   The FreeCol Team
+ *
+ *  This file is part of FreeCol.
+ *
+ *  FreeCol is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  FreeCol is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with FreeCol.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.sf.freecol.common.util;
+
+
+import java.lang.StringBuilder;
+
+
+public class StrCat {
+    private String delimiter = ", ";
+    private int counter = 0;
+    private StringBuilder sb = new StringBuilder();
+
+    public StrCat(String d) {
+        delimiter = d;
+    }
+
+    public final boolean isEmpty() {
+        return counter == 0;
+    }
+
+    /**
+     * directly add a string to the underlying buffer, w/o any
+     * any delimiter. also dont count that as an element.
+     */
+    public final StrCat append(String s) {
+        sb.append(s);
+        return this;
+    }
+
+    /**
+     * add another element and fill the delimiter
+     * in between it's not the first one.
+     */
+    public final void add(String s) {
+        if ((s == null) || s.equals("")) return;
+
+        if (counter == 0) {
+            sb.append(s);
+        } else {
+            sb.append(delimiter);
+            sb.append(s);
+        }
+        counter++;
+    }
+
+    public final String toString() {
+        return sb.toString();
+    }
+}
-- 
2.11.0.rc0.7.gbe5a750


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Freecol-developers mailing list
Freecol-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freecol-developers

Reply via email to