Is it possible to shorten this code? - java

I'm not exactly a beginner in Java, but I'm also not an expert. Is there any way to shorten this code so that it takes up less space and possibly fewer lines?
JOptionPane.showMessageDialog(null, "The student's names are: "
+ roster[0][0] + " " + roster[1][0] + ", "
+ roster[0][1] + " " + roster[1][1] + ", "
+ roster[0][2] + " " + roster[1][2] + ", and "
+ roster[0][3] + " " + roster[1][3] + ".");

Let's refactoring the code step by step
introduce variables to remove duplication.
T[] col1 = roster[0];
T[] col2 = roster[1];
String content = col1[0] + " " + col2[0] + ", "
+ col1[1] + " " + col2[1] + ", "
+ col1[2] + " " + col2[2] + ", and "
+ col1[3] + " " + col2[3] + ".";
JOptionPane.showMessageDialog(null,"The student's names are: " + content);
separate string concatenation into multi-assignments, then all assignments are the same except the last one.
int i = 0;
String content = "";
content += col1[i] + " " + col2[i] + ", ";i++;
content += col1[i] + " " + col2[i] + ", ";i++;
content += col1[i] + " " + col2[i] + ", ";i++;
content += "and " + col1[i] + " " + col2[i] + ".";i++;
make the multi-assignments consistent by using ternary operator.
int i = 0;
String content = "";
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", "); i++;
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", "); i++;
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", "); i++;
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", "); i++;
using while-loop to remove duplication.
int i = 0;
String content = "";
while(i<=3) {
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", ");
i++;
}
replacing while-loop with for-loop.
String content = "";
for (int i = 0; i <= 3; i++) {
content+= (i==3?"and ":"") + col1[i]+" "+col2[i] + (i==3?".":", ");
}
introduce variables to make the code more readable.
String content = "";
for (int i = 0; i <= 3; i++) {
String prefix = i == 3 ? "and " : "";
String current = col1[i] + " " + col2[i];
String suffix = i == 3 ? "." : ", ";
content += prefix + current + suffix;
}
inline the variables col1 & col2 that is used only once:
String content = "";
for (int i = 0; i <= 3; i++) {
String prefix = i == 3 ? "and " : "";
String current = roster[0][i] + " " + roster[1][i];
String suffix = i == 3 ? "." : ", ";
content += prefix + current + suffix;
}
replace magic number 3 with constant and the final code is below:
final int last = 3;
String content = "";
for (int i = 0; i <= last; i++) {
String prefix = i == last ? "and " : "";
String suffix = i == last ? "." : ", ";
String current = roster[0][i] + " " + roster[1][i];
content += prefix + current + suffix;
}
JOptionPane.showMessageDialog(null, "The student's names are: " + content);

StringBuilder message = new StringBuilder("The student's names are: ");
for (int i = 0; i < roster[0].length; i++) {
message
.append(roster[0][i])
.append(" ")
.append(roster[1][i]);
if (i < roster[0].length - 1)
message.append(", ");
if (i == roster[0].length - 2)
message.append("and ")
}
message.append(".");
JOptionPane.showMessageDialog(null, message.toString());
Possibly something like that. As you can see, you don't really save any lines, but obviously the code is more flexible as it can account for a variable length roster.

You can do the following: Initially assign the normal statement that you do not want repeated. Then loop through roster.
String rosterString= "The student's names are: ";
for(int i=0;i<= roster.length;i++){
for(int j=0;j<= roster[i].length;j++){
rosterString += (roster[i][j] + " ");
if (i == 1 && j < 2) {
rosterString += ", ";
}
else if (i == 1 && j == 2) {
rosterString += ", and";
}
else if (i == 1 && j == 3) {
rosterString += ".";
}
else {
rosterString += " ";
}
}
}
And then pass rosterString to your method.

String rosterString = "";
for(int i = 0; i < roster[0].length; i++) {
rosterString += roster[0][i] + " " + roster[1][i] + ", ";
}
That code will create a string with the names and commas. You could then add in if statements to check if it is near the end to change the , to an and or .

Related

How do I add "and" before the last author's last name?

public String Cite()
{
String authorsList = "";
Collections.sort(authors);
for(Author a: authors)
{
authorsList += a.firstName.toUpperCase().charAt(0) + ". " + a.lastName + ", ";
}
String cite = authorsList + "\"" + title + "\", " + venue + "(" + getAcronym() + ")" + " , " +
publisher;
return cite;
}
How would I go about adding the word "and" to separate the last two names of the list?
Use a for loop with index.
for (int i = 0; i < authors.size(); ++i) {
if (i == authors.size() - 2) {
authorsList += a.firstName.toUpperCase().charAt(0) + ". " + a.lastName + "and ";
} else {
authorsList += a.firstName.toUpperCase().charAt(0) + ". " + a.lastName + ", ";
}
}
public static String Cite(ArrayList<Author> authors){
String authorsList = "";
Collections.sort(authors, new CustomComperator());
int size = authors.size();
int count = 0;
for(Author a: authors) {
if (size ==1) {
authorsList = a.firstName.toUpperCase().charAt(0) + ". " + a.lastName;
}
else if (count == size-2) {
authorsList += a.firstName.toUpperCase().charAt(0) + ". " + a.lastName ;
}
else if (count == size - 1) {
authorsList += " and " + a.firstName.toUpperCase().charAt(0) + ". " + a.lastName ;
}
else{
authorsList += a.firstName.toUpperCase().charAt(0) + ". " + a.lastName + ", ";
}
count ++;
}
return authorsList;
}
You should use a normal for loop, so you can detect that you're on the first and/or last element.
Other changes:
Remove the , after the last author.
Use StringBuilder to build a String.
List<Author> authors = new ArrayList<>(List.of(
new Author("Stephen", "King"),
new Author("John", "Grisham"),
new Author("William", "Shakespeare"),
new Author("Charles", "Dickens") ));
Collections.sort(authors);
StringBuilder buf = new StringBuilder();
for (int i = 0; i < authors.size(); i++) {
Author a = authors.get(i);
if (i != 0)
buf.append(i < authors.size() - 1 ? ", " : " and ");
buf.append(a.firstName.toUpperCase().charAt(0) + ". " + a.lastName);
}
String authorsList = buf.toString();
System.out.println(authorsList);
Output
C. Dickens, J. Grisham, S. King and W. Shakespeare
Oxford comma
Whether or not you want , comma before and (Oxford comma) is of course entirely up to you.
buf.append(i < authors.size() - 1 ? ", " : ", and ");
Output
C. Dickens, J. Grisham, S. King, and W. Shakespeare
UPDATE
Since all 4 other answers at this time gave bad result for a single Author, here is test result for various number of authors.
Full Test
List<Author> allAuthors = List.of(
new Author("Stephen", "King"),
new Author("John", "Grisham"),
new Author("William", "Shakespeare"),
new Author("Charles", "Dickens") );
for (int aCount = 0; aCount <= allAuthors.size(); aCount++) {
List<Author> authors = new ArrayList<>(allAuthors.subList(0, aCount));
Collections.sort(authors);
StringBuilder buf = new StringBuilder();
for (int i = 0; i < authors.size(); i++) {
Author a = authors.get(i);
if (i != 0)
buf.append(i < authors.size() - 1 ? ", " : " and ");
buf.append(a.firstName.toUpperCase().charAt(0) + ". " + a.lastName);
}
String authorsList = buf.toString();
System.out.println(aCount + ": \"" + authorsList + "\"");
}
Output
0: ""
1: "S. King"
2: "J. Grisham and S. King"
3: "J. Grisham, S. King and W. Shakespeare"
4: "C. Dickens, J. Grisham, S. King and W. Shakespeare"
If you want to do the same without loops you could:
Define a toString or similar method inside your Author class:
class Author{
String firstName;
String lastName;
Author(String firstName,String lastName){
this.firstName=firstName;
this.lastName=lastName;
}
#Override
public String toString(){
return String.format("%s. %s",this.firstName.toUpperCase().charAt(0), this.lastName);
}
}
And use the Collectors.joining to create the initial list (comma separated).
List<Author> authors = Arrays.asList(new Author("Jules", "Verne"),
new Author("Pablo", "Neruda"), new Author("JK", "Rowling"));
authors.sort(Comparator.comparing(a -> a.lastName));
StringBuffer result = new StringBuffer(
authors.stream().limit(authors.size() - 1).map(a -> a.toString()).collect(
Collectors.joining(" ,")));
And after that, add the last "and":
if (authors.size() > 1) {
result.append(String.format(" and %s", authors.get(authors.size() - 1).toString()));
} else {
result.append(authors.get(authors.size() - 1).toString());
}
System.out.println(result);
Output: P. Neruda ,J. Rowling and J. Verne

Convert string with nested characters into specific json like format in java

There's a string like:
String query = "param1, param2, param3{npam1, npam2, npam3{nipam1, nipam2}}";
This string needs to be processed in the format:
{
param1: param1,
param2: param2,
param3: {
npam1: param3.npam1,
npam2: param3.npam2,
npam3: {
nipam1: param3.npam3.nipam1,
nipam2: param3.npam3.nipam2
}
}
}
Have already done till 2 nested, but the point is the string to query can be extended to any number of nested curls.
What I did was to iterate over the objects in the string and then iterate over the attributes of each object. Hopefully, it will help you to solve your problem. Also in your initial String, you are missing the open parenthesis and the close parenthesis so I added them.
String jsonWithOutFormat = "param1, param2, param3{npam1, npam2, npam3{nipam1, nipam2}}";
jsonWithOutFormat = jsonWithOutFormat.replaceAll(" ", "");
String json = "";
String[] objectsInString = jsonWithOutFormat.split("[{]");
List<String> nestedObjects = new ArrayList<>();
json += "{";
for (int i = 0; i < objectsInString.length; i++) {
String[] objectAttributes = objectsInString[i].split("[,]");
if(i==0)
nestedObjects.add(objectAttributes[objectAttributes.length-1] + ".");
else
nestedObjects.add(nestedObjects.get(i-1)+objectAttributes[objectAttributes.length-1] + ".");
for (int j = 0; j < objectAttributes.length; j++) {
if(!(j == objectAttributes.length-1)) {
if(i != 0)
json+= objectAttributes[j] + ": " + nestedObjects.get(i-1) + objectAttributes[j] + ", ";
else
json+= objectAttributes[j] + "\"" + ": " + "\"" + objectAttributes[j] + "\"" + ", ";
}
else {
if(!(i == objectsInString.length-1))
json+= objectAttributes[j] + ": {";
else {
json+= objectAttributes[j].replaceAll("}", "") + ": " + nestedObjects.get(i-1) + objectAttributes[j];
}
}
}
}
json += "}";
System.out.print("\n" + json);
}
Thanks Jorge. This method can be called to produce json in desired format, by passing the actual String (the one that is not formatted).
public String expressionConstruct(String jsonWithOutFormat) {
jsonWithOutFormat = jsonWithOutFormat.replaceAll(" ", "");
String json = "";
String[] objectsInString = jsonWithOutFormat.split("[{]");
List<String> nestedObjects = new ArrayList<>();
json += "{";
for (int i = 0; i < objectsInString.length; i++) {
String[] objectAttributes = objectsInString[i].split("[,]");
if(i==0)
nestedObjects.add(objectAttributes[objectAttributes.length-1] + ".");
else
nestedObjects.add(nestedObjects.get(i-1)+objectAttributes[objectAttributes.length-1] + ".");
for (int j = 0; j < objectAttributes.length; j++) {
if(!(j == objectAttributes.length-1)) {
if(i != 0)
json+= objectAttributes[j].replaceAll("}", "") + ": " + nestedObjects.get(i-1) + objectAttributes[j] + ", ";
else
json+= objectAttributes[j] + ": " + objectAttributes[j] + ", ";
}
else {
if(!(i == objectsInString.length-1))
json+= objectAttributes[j] + ": {";
else {
json+= objectAttributes[j].replaceAll("}", "") + ": " + nestedObjects.get(i-1) + objectAttributes[j];
}
}
}
}
json += "}";
return json;
}

How to search a token for a specific word in Java?

I have a segment of code that splits a string into tokens and prints them each out on a new line. I am having a hard time writing a code that determines if a word is a reserved word or not. I have to print "Reserved word is: " if the word is a java keyword, otherwise print "Current word is: ". Here is my code so far:
package projectweek3;
/**
*
* Name -
* Email Address -
* Date -
*
*/
public class Week3Project {
final static String program = "/*\n" +
" * To change this license header, choose License Headers in Project Properties.\n" +
" * To change this template file, choose Tools | Templates\n" +
" * and open the template in the editor.\n" +
" */\n" +
"package testapplication2;\n" +
"\n" +
"import java.util.Scanner;\n" +
"\n" +
"/**\n" +
" *\n" +
" * #author james\n" +
" */\n" +
"public class TestApplication2 {\n" +
"\n" +
" /**\n" +
" * #param args the command line arguments\n" +
" */\n" +
" public static void main(String[] args) {\n" +
" Scanner input = new Scanner(System.in);\n" +
" \n" +
" System.out.println(\"Enter integer #1\");\n" +
" int num1 = input.nextInt();\n" +
" \n" +
" System.out.println(\"Enter integer #2\");\n" +
" int num2 = input.nextInt();\n" +
" \n" +
" System.out.println(\"Enter integer #3\");\n" +
" int num3 = input.nextInt();\n" +
" \n" +
" System.out.println(\"Enter integer #4\");\n" +
" int num4 = input.nextInt();\n" +
" \n" +
" System.out.println(\"Enter integer #5\");\n" +
" int num5 = input.nextInt();\n" +
" \n" +
" //determine the sum\n" +
" int sum = num1 + num2 + num3 + num4 + num5;\n" +
" \n" +
" //this is helpful to make sure your sum is correct\n" +
" System.out.println(\"The sum is: \" + sum);\n" +
" \n" +
" //why doesn't this generate the sum correctly\n" +
" double average = sum / 5;\n" +
" \n" +
" //The average, lets hope its right...\n" +
" System.out.println(\"The average of your numbers is: \" + average);\n" +
" \n" +
" }\n" +
" \n" +
"}\n" +
"";
**public static void main(String[] args)
{
String str = program;
String s = "";
for (int i = 0; i < str.length(); i++) {
s += str.charAt(i) + "";
if (str.charAt(i) == ' ' || str.charAt(i) == '\t' || str.charAt(i) == '\n' || (str.charAt(i) == ' ' && str.charAt(i) == '\n')) {
String currentWord = s.toString();
String res = "int";
if (currentWord.equals(res)) {
System.out.println("Reserved word is: [" + currentWord + "]");
}
else {
System.out.println("Current word is: [" + currentWord + "]");
}
s = "";//Clear the string to get it ready to build next token.
}
}**
I would reconsider the way you're looping through the "program."
Instead of going through character by character, use the Java String.split() function.
String program = "int num1 = input.nextInt();\n";
String[] words = program.split("[\\n\\s\\t]");
for (String word : words) {
System.out.println(word);
}
Output:
int
num1
=
input.nextInt();
EDIT:
Since you can't use String.split(), your looping solution looks good. To check if the current word is reserved, try using Set.contains().
Set<String> reserved = new HashSet<>();
reserved.add("int");
// ...
if reserved.contains(word) {
System.out.println("Reserved word is: " + word);
} else {
System.out.println("Current word is: " + word);
}
That is, assuming you're allowed to use Set.

why does the following keep returning an out of bounds error?

Please help my figure out why this keeps throwing an out of bounds error. i tried making a separate loop keep track of AdminDecisions
String returnProfile() {
String uniPicksString ="";
String studentInfo = null;
//for(int i = 0; i<ApplicantArray.size(); i++) {
studentInfo =FAMILYNAME+ ", " + "average = " + AVERAGE + " ";
for (int j = 0; j<CHOICES.size(); j++) {
if(j<CHOICES.size() - 1) {
uniPicksString = uniPicksString + CHOICES.get(j)+ ": " + " admin decision, " ;
}else {
uniPicksString = uniPicksString + CHOICES.get(j)+ ": " + " admin decision" + "\n";
}
}
//}
return studentInfo + uniPicksString + "\n";
}
the following code shows the desired out put but i cant return it as a string
String printProof() {
// System.out.println("from inside the student class");
String temp=null;
d = new ArrayList<String>();
for(int j = 0 ; j<1; j++) {
System.out.print("\n >>printProof<< " + FAMILYNAME+", " + "average = " + AVERAGE + " ");
for (int i = 0; i<AdminDecision.size(); i++) {
//System.out.println(AdminDecision.get(i));
//temp = CHOICES.get(i)+ ": " + AdminDecision.get(i) + ", ";
if(i<CHOICES.size() - 1) {
temp = CHOICES.get(i)+ ": " + AdminDecision.get(i) + ", ";
}else {
temp = CHOICES.get(i)+ ": " + AdminDecision.get(i) + "\n";
}
System.out.print(temp + " ");
d.add(AdminDecision.get(i));
}
}
return temp + "\n";
}

clearing a JLabel not working [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have read several posts suggesting to clear a JLabel (displayEntered) on a panel (display) with text by using the setText(" "). However, I have tried this and the outcome is it is just posting the array entered twice and does not clear the first set. I have an action shown below when a button is pressed both times; the first is to enter the data entered (I have the same code 4 times for the 4 different possible objects to enter but just put in the one since it's basically the same), which works fine and the second is to remove a specific one shown. My code is long, so am just putting that in. If someone wants something else please let me know. Thanks, I'd appreciate any input!
//adds the Herb data to the Array and list
enterHerbData.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Enter")){
Name = NameTxt.getText();
Colors = ColorTxt.getText();
ID = (int) IDCmbo.getSelectedItem();
Flavor = FlavorTxt.getText();
if(((String) MedicinalCmbo.getSelectedItem()).equals("Yes"))
Medicinal = true;
else
Medicinal = false;
if(((String) SeasonalCmbo.getSelectedItem()).equals("Yes"))
Seasonal = true;
else
Seasonal = false;
plants[count] = new Herb(Name, ID, Colors, Flavor, Medicinal, Seasonal);
String displayArraytemp = " ";
if(plants[count] != null){
if(plants[count] instanceof Flower){
displayArraytemp = ((count + 1) + ": " + plants[count].getID() + ", " + plants[count].getName() + ", " + ((Flower)plants[count]).getColor() + ", " + ((Flower)plants[count]).getSmell() + ", Thorny: " + ((Flower)plants[count]).getThorns() + "\n");
}
else if(plants[count] instanceof Fungus){
displayArraytemp = ((count + 1) + ": " + plants[count].getID() + ", " + plants[count].getName() + ", " + ((Fungus)plants[count]).getColor() + ", Poisonous: " + ((Fungus)plants[count]).getPoisonous() + "\n");
}
else if(plants[count] instanceof Weed){
displayArraytemp = ((count + 1) + ": " + plants[count].getID() + ", " + plants[count].getName() + ", " + ((Weed)plants[count]).getColor() + ", Edible: " + ((Weed)plants[count]).getEdible() + ", Medicinal: " + ((Weed)plants[count]).getMedicinal() + ", Poisonous: " + ((Weed)plants[count]).getPoisonous() + "\n");
}
else if(plants[count] instanceof Herb){
displayArraytemp = ((count + 1) + ": " + plants[count].getID() + ", " + plants[count].getName() + ", " + ((Herb)plants[count]).getColor() + ", " + ((Herb)plants[count]).getFlavor() + ", Medicinal: " + ((Herb)plants[count]).getMedicinal() + ", Poisonous: " + ((Herb)plants[count]).getSeasonal() + "\n");
}
sb.append("<html>" + displayArraytemp).
append("<br> ");
displayArray = sb.toString();
}
displayEntered.setText(displayArray);
count++;
frameB.setVisible(false);
}
}
});
//removes the data to the Array and panel
ActionListener RemoveAction = new ActionListener(){
#Override
public void actionPerformed(ActionEvent RemoveAction){
if(RemoveAction.getActionCommand().equals("Enter")){
if((Btn1).isSelected()){
String displayArraytemp2 = " ";
if(count >= 1){
for(int n = 0; n < count; n++){
plants[n] = plants[n+1];
}
count--;
frameB.setVisible(false);
displayEntered.setOpaque(true);
for(int n = 0; n < 25; n++){
if(plants[n] != null){
if(plants[n] instanceof Flower){
displayArraytemp2 = ((n + 1) + ": " + plants[n].getID() + ", " + plants[n].getName() + ", " + ((Flower)plants[n]).getColor() + ", " + ((Flower)plants[n]).getSmell() + ", Thorny: " + ((Flower)plants[n]).getThorns() + "\n");
}
else if(plants[n] instanceof Fungus){
displayArraytemp2 = ((n + 1) + ": " + plants[n].getID() + ", " + plants[n].getName() + ", " + ((Fungus)plants[n]).getColor() + ", Poisonous: " + ((Fungus)plants[n]).getPoisonous() + "\n");
}
else if(plants[n] instanceof Weed){
displayArraytemp2 = ((n + 1) + ": " + plants[n].getID() + ", " + plants[n].getName() + ", " + ((Weed)plants[n]).getColor() + ", Edible: " + ((Weed)plants[n]).getEdible() + ", Medicinal: " + ((Weed)plants[n]).getMedicinal() + ", Poisonous: " + ((Weed)plants[n]).getPoisonous() + "\n");
}
else if(plants[n] instanceof Herb){
displayArraytemp2 = ((n + 1) + ": " + plants[n].getID() + ", " + plants[n].getName() + ", " + ((Herb)plants[n]).getColor() + ", " + ((Herb)plants[n]).getFlavor() + ", Medicinal: " + ((Herb)plants[n]).getMedicinal() + ", Poisonous: " + ((Herb)plants[n]).getSeasonal() + "\n");
}
sb.append("<html>" + displayArraytemp2).
append("<br> ");
displayArray = sb.toString();
}
}
}
displayEntered.setText(" ");
displayEntered.setText(displayArray);
}
}
}};
Your real problem is that you are re-using sb without clearing it.

Categories

Resources