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