From 5e22dc0b8f323b5c184b8882bf03c01479abc1c8 Mon Sep 17 00:00:00 2001 From: Eyre_S Date: Sat, 27 Nov 2021 21:07:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E9=A1=B9=E7=9B=AE=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=20null=20=E6=A0=87=E8=AE=B0=E5=92=8C=20final=20=E6=A0=87?= =?UTF-8?q?=E8=AE=B0=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 ++- .../java/cc/sukazyo/cono/morny/Logger.java | 19 +++++++----- .../cc/sukazyo/cono/morny/MornyCoeur.java | 11 ++++--- .../cc/sukazyo/cono/morny/MornySystem.java | 4 ++- .../cc/sukazyo/cono/morny/MornyTrusted.java | 2 +- .../cono/morny/bot/api/EventListener.java | 28 +++++++++-------- .../morny/bot/api/EventListenerManager.java | 31 ++++++++++--------- .../sukazyo/cono/morny/bot/api/OnUpdate.java | 3 +- .../morny/bot/event/OnActivityRecord.java | 4 ++- .../morny/bot/event/OnCommandExecute.java | 14 +++++---- .../morny/bot/event/OnUserSlashAction.java | 18 ++++++----- .../event/on_commands/GetUsernameAndId.java | 10 +++--- .../cc/sukazyo/cono/morny/util/FileUtils.java | 16 +++++----- .../sukazyo/cono/morny/util/StringUtils.java | 23 +++++++++----- 14 files changed, 109 insertions(+), 79 deletions(-) diff --git a/build.gradle b/build.gradle index 0bd3331..aa1d3c0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,13 @@ plugins { id 'java' + id 'java-library' id 'maven-publish' id 'application' id 'com.github.johnrengelman.shadow' version '7.1.0' } group 'cc.sukazyo' -version '0.3.3' +version '0.3.4' project.ext.archiveBaseName = 'Coeur_Morny_Cono' project.ext.artifactId = 'morny-coeur' mainClassName = 'cc.sukazyo.cono.morny.MornyCoeur' @@ -17,6 +18,8 @@ repositories { dependencies { + compileOnlyApi "com.github.spotbugs:spotbugs-annotations:4.5.0" + implementation 'com.github.pengrad:java-telegram-bot-api:5.3.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' diff --git a/src/main/java/cc/sukazyo/cono/morny/Logger.java b/src/main/java/cc/sukazyo/cono/morny/Logger.java index 9727f55..266f3c4 100644 --- a/src/main/java/cc/sukazyo/cono/morny/Logger.java +++ b/src/main/java/cc/sukazyo/cono/morny/Logger.java @@ -2,30 +2,33 @@ package cc.sukazyo.cono.morny; import cc.sukazyo.cono.morny.util.StringUtils; +import javax.annotation.Nonnull; + public class Logger { public static final Logger logger = new Logger(); - public void info(String message) { + public void info(@Nonnull String message) { System.out.println(formatMessage(message, "INFO")); } - public void warn (String message) { + public void warn (@Nonnull String message) { waring(message); } - public void waring (String message) { + public void waring (@Nonnull String message) { System.out.println(formatMessage(message, "WARN")); } - public void error (String message) { + public void error (@Nonnull String message) { System.out.println(formatMessage(message, "ERRO")); } - private String formatMessage (String message, String level) { - String prompt = String.format("[%s][%s]", System.currentTimeMillis(), Thread.currentThread().getName()); - String levelStr = String.format("[%s]", level); - String newline = "\n" + StringUtils.repeatChar('\'', prompt.length()) + levelStr; + @Nonnull + private String formatMessage (@Nonnull String message, @Nonnull String level) { + final String prompt = String.format("[%s][%s]", System.currentTimeMillis(), Thread.currentThread().getName()); + final String levelStr = String.format("[%s]", level); + final String newline = "\n" + StringUtils.repeatChar('\'', prompt.length()) + levelStr; return prompt + levelStr + message.replaceAll("\\n", newline); } diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java index f652188..a35aeaa 100644 --- a/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java +++ b/src/main/java/cc/sukazyo/cono/morny/MornyCoeur.java @@ -6,6 +6,8 @@ import cc.sukazyo.cono.morny.data.tracker.TrackerDataManager; import com.pengrad.telegrambot.TelegramBot; import com.pengrad.telegrambot.request.GetMe; +import javax.annotation.Nonnull; + import static cc.sukazyo.cono.morny.Logger.logger; public class MornyCoeur { @@ -13,7 +15,7 @@ public class MornyCoeur { private static TelegramBot account; public static final String USERNAME = "morny_cono_annie_bot"; - public static void main (String[] args) { + public static void main (@Nonnull String[] args) { if (!(args.length > 1 && "--no-hello".equals(args[1]))) logger.info(MornyHello.MORNY_PREVIEW_IMAGE_ASCII); @@ -47,13 +49,14 @@ public class MornyCoeur { Runtime.getRuntime().addShutdownHook(new Thread(MornyCoeur::exitCleanup)); } - public static TelegramBot login (String key) { - TelegramBot account = new TelegramBot(key); + @Nonnull + public static TelegramBot login (@Nonnull String key) { + final TelegramBot account = new TelegramBot(key); logger.info("Trying to login..."); for (int i = 1; i < 4; i++) { if (i != 1) logger.info("retrying..."); try { - String username = account.execute(new GetMe()).user().username(); + final String username = account.execute(new GetMe()).user().username(); if (!USERNAME.equals(username)) throw new RuntimeException("Required the bot @"+USERNAME + " but @"+username + " logged in!"); logger.info("Succeed login to @" + username); diff --git a/src/main/java/cc/sukazyo/cono/morny/MornySystem.java b/src/main/java/cc/sukazyo/cono/morny/MornySystem.java index 49e8a08..5de6c7d 100644 --- a/src/main/java/cc/sukazyo/cono/morny/MornySystem.java +++ b/src/main/java/cc/sukazyo/cono/morny/MornySystem.java @@ -2,12 +2,14 @@ package cc.sukazyo.cono.morny; import cc.sukazyo.cono.morny.util.FileUtils; +import javax.annotation.Nonnull; import java.net.URISyntaxException; public class MornySystem { - public static final String VERSION = "0.3.3"; + public static final String VERSION = "0.3.4"; + @Nonnull public static String getJarMd5() { try { return FileUtils.getMD5Three(MornyCoeur.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); diff --git a/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java b/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java index a1bd6d5..862fd44 100644 --- a/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java +++ b/src/main/java/cc/sukazyo/cono/morny/MornyTrusted.java @@ -8,7 +8,7 @@ public class MornyTrusted { public static final long TRUSTED_CHAT_ID = -1001541451710L; public static boolean isTrusted (long userId) { - ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember(); + final ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember(); return ( chatMember != null && ( chatMember.status() == ChatMember.Status.administrator || diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java index 6c5114d..73e4c1a 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListener.java @@ -2,58 +2,60 @@ package cc.sukazyo.cono.morny.bot.api; import com.pengrad.telegrambot.model.Update; +import javax.annotation.Nonnull; + @SuppressWarnings("unused") public abstract class EventListener { - public boolean onMessage (Update update) { + public boolean onMessage (@Nonnull Update update) { return false; } - public boolean onEditedMessage (Update update) { + public boolean onEditedMessage (@Nonnull Update update) { return false; } - public boolean onChannelPost (Update update) { + public boolean onChannelPost (@Nonnull Update update) { return false; } - public boolean onEditedChannelPost (Update update) { + public boolean onEditedChannelPost (@Nonnull Update update) { return false; } - public boolean onInlineQuery (Update update) { + public boolean onInlineQuery (@Nonnull Update update) { return false; } - public boolean onChosenInlineResult (Update update) { + public boolean onChosenInlineResult (@Nonnull Update update) { return false; } - public boolean onCallbackQuery (Update update) { + public boolean onCallbackQuery (@Nonnull Update update) { return false; } - public boolean onShippingQuery (Update update) { + public boolean onShippingQuery (@Nonnull Update update) { return false; } - public boolean onPreCheckoutQuery (Update update) { + public boolean onPreCheckoutQuery (@Nonnull Update update) { return false; } - public boolean onPoll (Update update) { + public boolean onPoll (@Nonnull Update update) { return false; } - public boolean onPollAnswer (Update update) { + public boolean onPollAnswer (@Nonnull Update update) { return false; } - public boolean onMyChatMemberUpdated (Update update) { + public boolean onMyChatMemberUpdated (@Nonnull Update update) { return false; } - public boolean onChatMemberUpdated (Update update) { + public boolean onChatMemberUpdated (@Nonnull Update update) { return false; } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java index 9b59bb1..5ac91a6 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/EventListenerManager.java @@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.api; import com.pengrad.telegrambot.model.Update; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -17,7 +18,7 @@ public class EventListenerManager { private final Function exec; - public EventPublisher(Update update, Function exec) { + public EventPublisher(@Nonnull Update update, @Nonnull Function exec) { this.setName("EVT"+update.updateId()); this.exec = exec; } @@ -36,59 +37,59 @@ public class EventListenerManager { } - public static void addListener (EventListener... listeners) { + public static void addListener (@Nonnull EventListener... listeners) { EventListenerManager.listeners.addAll(Arrays.asList(listeners)); } - public static void publishMessageEvent (Update update) { + public static void publishMessageEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onMessage(update)).start(); } - public static void publishEditedMessageEvent (Update update) { + public static void publishEditedMessageEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onEditedMessage(update)).start(); } - public static void publishChannelPostEvent (Update update) { + public static void publishChannelPostEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onChannelPost(update)).start(); } - public static void publishEditedChannelPostEvent (Update update) { + public static void publishEditedChannelPostEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onEditedChannelPost(update)).start(); } - public static void publishInlineQueryEvent (Update update) { + public static void publishInlineQueryEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onInlineQuery(update)).start(); } - public static void publishChosenInlineResultEvent (Update update) { + public static void publishChosenInlineResultEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onChosenInlineResult(update)).start(); } - public static void publishCallbackQueryEvent (Update update) { + public static void publishCallbackQueryEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onCallbackQuery(update)).start(); } - public static void publishShippingQueryEvent (Update update) { + public static void publishShippingQueryEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onShippingQuery(update)).start(); } - public static void publishPreCheckoutQueryEvent (Update update) { + public static void publishPreCheckoutQueryEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onPreCheckoutQuery(update)).start(); } - public static void publishPollEvent (Update update) { + public static void publishPollEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onPoll(update)).start(); } - public static void publishPollAnswerEvent (Update update) { + public static void publishPollAnswerEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onPollAnswer(update)).start(); } - public static void publishMyChatMemberUpdatedEvent (Update update) { + public static void publishMyChatMemberUpdatedEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onMyChatMemberUpdated(update)).start(); } - public static void publishChatMemberUpdatedEvent (Update update) { + public static void publishChatMemberUpdatedEvent (@Nonnull Update update) { new EventPublisher(update, x -> x.onChatMemberUpdated(update)).start(); } diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java b/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java index f45671e..8427283 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/api/OnUpdate.java @@ -3,11 +3,12 @@ package cc.sukazyo.cono.morny.bot.api; import com.pengrad.telegrambot.UpdatesListener; import com.pengrad.telegrambot.model.Update; +import javax.annotation.Nonnull; import java.util.List; public class OnUpdate { - public static int onNormalUpdate (List updates) { + public static int onNormalUpdate (@Nonnull List updates) { for (Update update : updates) { if (update.message() != null) { EventListenerManager.publishMessageEvent(update); diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnActivityRecord.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnActivityRecord.java index adbd3b3..9c3ed6e 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnActivityRecord.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnActivityRecord.java @@ -5,10 +5,12 @@ import cc.sukazyo.cono.morny.data.tracker.TrackerDataManager; import com.pengrad.telegrambot.model.Chat; import com.pengrad.telegrambot.model.Update; +import javax.annotation.Nonnull; + public class OnActivityRecord extends EventListener { @Override - public boolean onMessage (Update update) { + public boolean onMessage (@Nonnull Update update) { if ( update.message().chat().type() == Chat.Type.supergroup || update.message().chat().type() == Chat.Type.group diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java index 389b329..cc7ee14 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnCommandExecute.java @@ -11,6 +11,8 @@ import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.request.SendSticker; +import javax.annotation.Nonnull; + import static cc.sukazyo.cono.morny.Logger.logger; public class OnCommandExecute extends EventListener { @@ -21,11 +23,11 @@ public class OnCommandExecute extends EventListener { private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA"; @Override - public boolean onMessage (Update event) { + public boolean onMessage (@Nonnull Update event) { if (event.message().text() == null) { return false; } - String[] command = StringUtils.formatCommand(event.message().text()); + final String[] command = StringUtils.formatCommand(event.message().text()); if (command.length == 0) return false; switch (command[0]) { case "/user": @@ -56,7 +58,7 @@ public class OnCommandExecute extends EventListener { return true; } - private void onCommandOnExec (Update event) { + private void onCommandOnExec (@Nonnull Update event) { MornyCoeur.getAccount().execute(new SendSticker( event.message().chat().id(), ONLINE_STATUS_RETURN_STICKER_ID @@ -64,7 +66,7 @@ public class OnCommandExecute extends EventListener { ); } - private void onCommandHelloExec (Update event) { + private void onCommandHelloExec (@Nonnull Update event) { MornyCoeur.getAccount().execute(new SendSticker( event.message().chat().id(), HELLO_STICKER_ID @@ -72,7 +74,7 @@ public class OnCommandExecute extends EventListener { ); } - private void onCommandExitExec (Update event) { + private void onCommandExitExec (@Nonnull Update event) { if (MornyTrusted.isTrusted(event.message().from().id())) { MornyCoeur.getAccount().execute(new SendSticker( event.message().chat().id(), @@ -91,7 +93,7 @@ public class OnCommandExecute extends EventListener { } } - private void onCommandVersionExec (Update event) { + private void onCommandVersionExec (@Nonnull Update event) { MornyCoeur.getAccount().execute(new SendMessage( event.message().chat().id(), String.format( diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java index b43b554..19db7e5 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/OnUserSlashAction.java @@ -8,11 +8,13 @@ import com.pengrad.telegrambot.model.User; import com.pengrad.telegrambot.model.request.ParseMode; import com.pengrad.telegrambot.request.SendMessage; +import javax.annotation.Nonnull; + public class OnUserSlashAction extends EventListener { @Override - public boolean onMessage (Update event) { - String text = event.message().text(); + public boolean onMessage (@Nonnull Update event) { + final String text = event.message().text(); if (text == null) return false; if (text.startsWith("/")) { @@ -31,12 +33,12 @@ public class OnUserSlashAction extends EventListener { prefixLength = 2; } - String[] action = StringUtils.formatCommand(text.substring(prefixLength)); - String verb = action[0]; - boolean hasObject = action.length != 1; - String object = StringUtils.connectStringArray(action, " ", 1, action.length-1); - User origin = event.message().from(); - User target = (event.message().replyToMessage() == null ? ( + final String[] action = StringUtils.formatCommand(text.substring(prefixLength)); + final String verb = action[0]; + final boolean hasObject = action.length != 1; + final String object = StringUtils.connectStringArray(action, " ", 1, action.length-1); + final User origin = event.message().from(); + final User target = (event.message().replyToMessage() == null ? ( origin ): ( event.message().replyToMessage().from() diff --git a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java b/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java index f896e50..b575fb5 100644 --- a/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java +++ b/src/main/java/cc/sukazyo/cono/morny/bot/event/on_commands/GetUsernameAndId.java @@ -8,9 +8,11 @@ import com.pengrad.telegrambot.request.GetChatMember; import com.pengrad.telegrambot.request.SendMessage; import com.pengrad.telegrambot.response.GetChatMemberResponse; +import javax.annotation.Nonnull; + public class GetUsernameAndId { - public static void exec (String[] command, Update event) { + public static void exec (@Nonnull String[] command, @Nonnull Update event) { if (command.length > 2) { MornyCoeur.getAccount().execute(new SendMessage( event.message().chat().id(), @@ -42,7 +44,7 @@ public class GetUsernameAndId { return; } - GetChatMemberResponse response = MornyCoeur.getAccount().execute( + final GetChatMemberResponse response = MornyCoeur.getAccount().execute( new GetChatMember(event.message().chat().id(), userId) ); @@ -54,9 +56,9 @@ public class GetUsernameAndId { return; } - User user = response.chatMember().user(); + final User user = response.chatMember().user(); - StringBuilder userInformation = new StringBuilder(); + final StringBuilder userInformation = new StringBuilder(); userInformation.append(String.format( "userid :\n" + "- %d\n" + diff --git a/src/main/java/cc/sukazyo/cono/morny/util/FileUtils.java b/src/main/java/cc/sukazyo/cono/morny/util/FileUtils.java index 73b17eb..c64a3db 100644 --- a/src/main/java/cc/sukazyo/cono/morny/util/FileUtils.java +++ b/src/main/java/cc/sukazyo/cono/morny/util/FileUtils.java @@ -1,6 +1,6 @@ package cc.sukazyo.cono.morny.util; -import java.io.File; +import javax.annotation.Nonnull; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; @@ -9,19 +9,19 @@ import java.security.NoSuchAlgorithmException; public class FileUtils { - public static String getMD5Three (String path) { - BigInteger bi; + @Nonnull + public static String getMD5Three (@Nonnull String path) { + final BigInteger bi; try { - byte[] buffer = new byte[8192]; + final byte[] buffer = new byte[8192]; int len; - MessageDigest md = MessageDigest.getInstance("MD5"); - File f = new File(path); - FileInputStream fis = new FileInputStream(f); + final MessageDigest md = MessageDigest.getInstance("MD5"); + final FileInputStream fis = new FileInputStream(path); while ((len = fis.read(buffer)) != -1) { md.update(buffer, 0, len); } fis.close(); - byte[] b = md.digest(); + final byte[] b = md.digest(); bi = new BigInteger(1, b); } catch (NoSuchAlgorithmException | IOException e) { e.printStackTrace(System.out); diff --git a/src/main/java/cc/sukazyo/cono/morny/util/StringUtils.java b/src/main/java/cc/sukazyo/cono/morny/util/StringUtils.java index 1a31249..7ff40c2 100644 --- a/src/main/java/cc/sukazyo/cono/morny/util/StringUtils.java +++ b/src/main/java/cc/sukazyo/cono/morny/util/StringUtils.java @@ -1,22 +1,26 @@ package cc.sukazyo.cono.morny.util; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Arrays; public class StringUtils { + @Nonnull public static String repeatChar (char c, int i) { - char[] chars = new char[i]; + final char[] chars = new char[i]; Arrays.fill(chars, c); return new String(chars); } - public static String[] formatCommand (String com) { + @Nonnull + public static String[] formatCommand (@Nonnull String com) { - ArrayList arr = new ArrayList<>(); + final ArrayList arr = new ArrayList<>(); - StringBuilder tmp = new StringBuilder(); - char[] coma = com.toCharArray(); + final StringBuilder tmp = new StringBuilder(); + final char[] coma = com.toCharArray(); for (int i = 0; i < coma.length; i++) { if (coma[i] == ' ') { if (!tmp.toString().equals("")) { arr.add(tmp.toString()); } @@ -43,14 +47,17 @@ public class StringUtils { if (!tmp.toString().equals("")) { arr.add(tmp.toString()); } tmp.setLength(0); - String[] out = new String[arr.size()]; + final String[] out = new String[arr.size()]; arr.toArray(out); return out; } - public static String connectStringArray (String[] array, String connector, int startIndex, int stopIndex) { - StringBuilder builder = new StringBuilder(); + @Nonnull + public static String connectStringArray ( + @Nonnull String[] array, @Nonnull String connector, @Nonnegative int startIndex, @Nonnegative int stopIndex + ) { + final StringBuilder builder = new StringBuilder(); for (int i = startIndex; i < stopIndex; i++) { builder.append(array[i]); builder.append(connector);