I am working on a custom Linked List based on Crunchify's implementation to display list of Employee. As of now I can add new Employee or remove existing Employee from the list. However, my project requires adding a sorting method that would not be based on Collections.sort(). My teacher wants this sorting method to be custom, so this is quite difficult for me. Is there anyway to sort this list by first name that is easy to code (I'm completely new to object oriented programming)?
Here is my custom Linked List:
import java.util.Scanner;
import java.io.IOException;
public class MyLinkedListTest2 {
public static MyLinkedList linkededList;
public static void main(String[] args) {
linkededList = new MyLinkedList();
linkededList.add(new Employee("Agness", "Bed", 2000.0, 32));
linkededList.add(new Employee("Adriano", "Phuks", 4000.0, 16));
linkededList.add(new Employee("Panda", "Mocs", 6000.0, 35));
System.out.println(linkededList);
//OPTIONS
Scanner scanner = new Scanner(System.in);
int selection;
do {
System.out.println("OPTIONS:\n[1] ADD EMPLOYEE\n[2] REMOVE EMPLOYEE\n[3] SORT \n[4] EXIT\n");
selection = scanner.nextInt();
switch (selection) {
case 1:
System.out.println("Name:");
scanner.nextLine();
String name = scanner.nextLine();
System.out.println("Surname:");
String surname = scanner.nextLine();
System.out.println("Salary:");
double salary = scanner.nextDouble();
System.out.println("Experience:");
int experience = scanner.nextInt();
linkededList.add(new Employee(name, surname, salary, experience));
System.out.println(linkededList);
break;
case 2:
System.out.println("Which row do you want to remove?");
int choice = scanner.nextInt();
if (choice == 0)
System.out.println("No such row exists");
else if (choice > linkededList.size())
System.out.println("No such row exists");
else
linkededList.remove(choice - 1);
System.out.println(linkededList);
break;
case 3:
System.out.println("SORT BY: 1.NAME\t2.SURNAME\t3.SALARY\t4.EXPERIENCE\n");
//In this section sorting algorithm should be added
break;
case 4:
break;
default:
System.out.println("Wrong choice");
}
} while (selection != 4);
}
}
class MyLinkedList<Employee> {
private static int counter;
private Node head;
public MyLinkedList() {
}
public void add(Object data) {
if (head == null) {
head = new Node(data);
}
Node myTemp = new Node(data);
Node myCurrent = head;
if (myCurrent != null) {
while (myCurrent.getNext() != null) {
myCurrent = myCurrent.getNext();
}
myCurrent.setNext(myTemp);
}
incrementCounter();
}
private static int getCounter() {
return counter;
}
private static void incrementCounter() {
counter++;
}
private void decrementCounter() {
counter--;
}
public void add(Object data, int index) {
Node myTemp = new Node(data);
Node myCurrent = head;
if (myCurrent != null) {
for (int i = 0; i < index && myCurrent.getNext() != null; i++) {
myCurrent = myCurrent.getNext();
}
}
myTemp.setNext(myCurrent.getNext());
myCurrent.setNext(myTemp);
incrementCounter();
}
public Object get(int index){
if (index < 0)
return null;
Node myCurrent = null;
if (head != null) {
myCurrent = head.getNext();
for (int i = 0; i < index; i++) {
if (myCurrent.getNext() == null)
return null;
myCurrent = myCurrent.getNext();
}
return myCurrent.getData();
}
return myCurrent;
}
public boolean remove(int index) {
if (index < 1 || index > size())
return false;
Node myCurrent = head;
if (head != null) {
for (int i = 0; i < index; i++) {
if (myCurrent.getNext() == null)
return false;
myCurrent = myCurrent.getNext();
}
myCurrent.setNext(myCurrent.getNext().getNext());
decrementCounter();
return true;
}
return false;
}
public int size() {
return getCounter();
}
public String toString() {
String output = "";
if (head != null) {
Node myCurrent = head.getNext();
while (myCurrent != null) {
output += myCurrent.getData().toString();
myCurrent = myCurrent.getNext();
}
}
return output;
}
public void compare(int index){
Node myCurrent = head.getNext();
if(myCurrent != myCurrent.getNext())
myCurrent = head;
else
myCurrent = myCurrent.getNext();
}
private class Node {
Node next;
Object data;
public Node(Object dataValue) {
next = null;
data = dataValue;
}
#SuppressWarnings("unused")
public Node(Object dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
public Object getData() {
return data;
}
#SuppressWarnings("unused")
public void setData(Object dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Also, here is my Employee class that the list is based on:
public class Employee
{
private String firstName;
private String lastName;
private double salary;
private int experience;
public Employee(String firstName, String lastName, double salary, int experience)
{
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
this.experience = experience;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public double getSalary()
{
return salary;
}
public int getExperience()
{
return experience;
}
#Override
public String toString()
{
String ret = "\n" +"Name: "+firstName +" | Surname: "+lastName +" | Salary: "+salary + " | Experience: "+experience +"\n";
return ret;
}
}
The code is compiling now, but maybe you have some recommendation regarding this implementation of Linked List? I would be grateful if someone comes up with a solution for sorting, since with this my project will be completed. Only Comparable can be used, while Collections.sort() method cannot be implemented due to project's requirements.
You can define your own EmployeeComparator that implements Comparator<Employee> (see comparator) and use it like following :
SortedSet<Employee> set = new TreeSet<Employee>(new EmployeeComparator());
set.addAll(employees);
Since you need to implement the sorting yourself, one of the easiest way could be so compare each list node with the next one and swap them if they are not in sorted order. You need to do this until there is any such out of order nodes left in the list.
You can see bubble sort implementation for an idea on how this works.
I have an assignment to make this Restaurant Program. it Consists of an Order Class a product class and the main class. Order has an ArrayList to hold the products. I create an instance of the Order and then I add items through my main method.A product has a name(string) a bar-code(string), and a price(float).
Then I have to output a receipt.But what if a customer orders more of one product? Do I instantiate everything one by one? Is a second Beer Product independent? Should I hold quantities somehow? If I want to add a second beer I have to create a new product Beer2 etc? I don't know beforehand how many products each order will hold and the quantity of each so Is this way of instantiating proper? Thanks
Note: it is still incomplete as I want to deal with this before I move on.
import java.util.Date;
public class MyRestaurantTester {
public static void main(String[] args) {
Date currentDate = new Date();
Paraggelia order1 = new Paraggelia(currentDate,"11B");
Product Beer = new Product("Amstel","111222",1.20f);
Product Beef = new Product("Pork Beef","333444",8.50f);
order1.add(Beer);
order1.add(Beef);
System.out.println(order1.getReceipt(30f));
}
}
Order Class(nevermind the name Paraggelia I gave it)
import java.util.ArrayList;
import java.util.Date;
/*Notes to self:
* -Work on Comments
* -Javadocs maybe?
* -try to optimize the rough code.
*/
/*Order class*/
public class Paraggelia {
private Date orderDate;
private String tableNumber;
private int customerCount;
private ArrayList<Product> listOfItems;
/*Constructor(s)*/
Paraggelia(Date orderDate,String tableNumber){
this.orderDate=orderDate;
this.tableNumber=tableNumber;
this.listOfItems = new ArrayList<Product>();
}
/*Add && Delete Products from the Order class*/
public void add(Product p){
if(p == null)
{
throw new IllegalArgumentException();
}else{
listOfItems.add(p);
}
}
public void delete(Product p){
if(p == null)
{
throw new IllegalArgumentException();
}
else
{
listOfItems.remove(p);
}
}
/** Calculates and returns the total price
* Usually called directly as a parameter of getReceipt function
* */
public static float getTotalPrice(){
return 0;
}
/** Creates and returns the final Receipt!
* -Display must consist of:
* Item$ - BarCode# - Item Amount#
* Total Price#
* Table Number#
*/
public String getReceipt(float totalPrice){
StringBuilder receipt = new StringBuilder();
for(int i =0; i<this.listOfItems.size();i++){
receipt.append(listOfItems.get(i).getName());
receipt.append("\n");
}
return new String(receipt);
}
/*Getters && Setters */
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public String getTableNumber() {
return tableNumber;
}
public void setTableNumber(String tableNumber) {
this.tableNumber = tableNumber;
}
public int getCustomerCount() {
return customerCount;
}
public void setCustomerCount(int customerCount) {
this.customerCount = customerCount;
}
}
Product Class:
public class Product {
private String Name;
private String barCode;
private float sellingPrice;
/*Constructors: */
Product(){}
Product(String Name,String barCode,float sellingPrice){
this.Name=Name;
this.barCode=barCode;
this.sellingPrice=sellingPrice;
}
/*Getters & Setters*/
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getBarCode() {
return barCode;
}
public void setBarCode(String barCode) {
this.barCode = barCode;
}
public float getSellingPrice() {
return sellingPrice;
}
public void setSellingPrice(float sellingPrice) {
this.sellingPrice = sellingPrice;
}
}
Instead of ArrayList ( List ) you can use Map ( HashMap for example )
MyRestaurantTester
public class MyRestaurantTester {
public static void main(String[] args) {
Date currentDate = new Date();
Paraggelia order1 = new Paraggelia(currentDate,"11B");
Product Beer = new Product("Amstel","111222",1.20f);
Product Beef = new Product("Pork Beef","333444",8.50f);
order1.add(Beer, 1);
order1.add(Beef, 5);
System.out.println(order1.getReceipt(30f));
}
}
Paraggelia
class Paraggelia {
private Date orderDate;
private String tableNumber;
private int customerCount;
private Map<Product, Integer> listOfItems;
/*Constructor(s)*/
Paraggelia(Date orderDate,String tableNumber){
this.orderDate=orderDate;
this.tableNumber=tableNumber;
this.listOfItems = new HashMap<Product, Integer>();
}
/*Add && Delete Products from the Order class*/
public void add(Product p, int quantity){
if(p == null)
{
throw new IllegalArgumentException();
}else{
listOfItems.put(p, quantity);
}
}
public void delete(Product p){
if(p == null)
{
throw new IllegalArgumentException();
}
else
{
listOfItems.remove(p);
}
}
/** Calculates and returns the total price
* Usually called directly as a parameter of getReceipt function
* */
public static float getTotalPrice(){
return 0;
}
/** Creates and returns the final Receipt!
* -Display must consist of:
* Item$ - BarCode# - Item Amount#
* Total Price#
* Table Number#
*/
public String getReceipt(float totalPrice){
StringBuilder receipt = new StringBuilder();
for(Map.Entry<Product,Integer> entry : this.listOfItems.entrySet()) {
Product product = entry.getKey();
Integer quantity = entry.getValue();
receipt.append(product.getName() + " " + quantity);
receipt.append("\n");
}
return new String(receipt);
}
/*Getters && Setters */
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public String getTableNumber() {
return tableNumber;
}
public void setTableNumber(String tableNumber) {
this.tableNumber = tableNumber;
}
public int getCustomerCount() {
return customerCount;
}
public void setCustomerCount(int customerCount) {
this.customerCount = customerCount;
}
}
OUTPUT:
Pork Beef 5
Amstel 1
Three basic approaches come to mind:
Instantiate each product individually
Instead of ArrayList, have another structure that can associate items with quantities; or,
Make a class Article, which belongs to a Product: Product beerProduct = new Product("beer", "0129", 1.37); Article beer = new Article(beerProduct), beer2 = new Article(beerProduct).
The first solution gives you a lot of flexibility (e.g. to discount individual articles for, say, being damaged). The second solution is more economical with objects. The third one captures the intuition that all the Heineken bottles are the same. It is really up to what you want to do - both approaches are equally valid, for some purpose.
I need help with this code. I need to call the quicksort method without any parameters in the main method. But this program has a parameter. How can I make it work and not have any parameter when calling it in the main method?
Please help.
Employee Class
public class Employee
{
private String firstname;
private int idNumber;
private String lastname;
Employee(String lname,String fname, int id)
{
lastname = lname;
firstname = fname;
idNumber = id;
}
public void setLastName(String lname)
{lastname = lname;}
public String getLastName()
{return lastname;}
public void setFirstName(String fname)
{firstname = fname;}
public String getFirstName()
{return firstname;}
public void setidNumber(int id)
{idNumber = id;}
public int getidNumber()
{return idNumber;}
public String toString()
{
String str = "\nName: " + lastname + " " + firstname
+ "\nID: " + idNumber;
return str;
}
public int compareTo(Employee Employee2)
{
int diff = lastname.compareToIgnoreCase(Employee2.getLastName());
if(diff != 0)
return diff;
else
return -1;
}
}
Linked List Class
public class DoublyLinkedList
{
public class DoublyLinkedListLink
{
public Employee info;
public DoublyLinkedListLink next;
public DoublyLinkedListLink back;
//Default Constructor
//Postcondition: info = 0;
// next = null; back = null;
public DoublyLinkedListLink()
{
info = null;
next = null;
back = null;
}
public DoublyLinkedListLink(Employee item)
{
info = item;
next = null;
back = null;
}
public void displayInfo()
{
System.out.print(info + " ");
}
}
protected int count;
protected DoublyLinkedListLink first;
protected DoublyLinkedListLink last;
public DoublyLinkedList()
{
first = null;
last = null;
count = 0;
}
public void initializeList()
{
first = null;
last = null;
count = 0;
}
public boolean isEmpty()
{
return (first == null);
}
public int length()
{
return count;
}
public void print()
{
DoublyLinkedListLink current = first;
while (current != null)
{
current.displayInfo();
current = current.next;
}//end while
}//end print
public void insert(Employee insertItem)
{
DoublyLinkedListLink newNode = new DoublyLinkedListLink(insertItem);
if (isEmpty())
{
first = newNode;
last = newNode;
count++;
}
else
{
last.next = newNode;
newNode.back = last;
}
last = newNode;
}
public DoublyLinkedListLink partition(DoublyLinkedList list, DoublyLinkedListLink first, DoublyLinkedListLink last)
{
DoublyLinkedListLink smallIndex = first;
DoublyLinkedListLink index = smallIndex.next;
DoublyLinkedListLink temp = new DoublyLinkedListLink();
Employee pivot = first.info;
while (index != last.next)
{
if((index.info).compareTo(pivot) <= 0)
{
smallIndex = smallIndex.next;
temp.info = index.info;
index.info = smallIndex.info;
smallIndex.info = temp.info;
}
index = index.next;
}
temp.info = first.info;
first.info = smallIndex.info;
smallIndex.info = temp.info;
System.out.print("The list in partition is: "); list.print();
System.out.print("\n");
return smallIndex;
}
private void recQuickSort(DoublyLinkedList list, DoublyLinkedListLink first, DoublyLinkedListLink last)
{
while(first != last)
{
DoublyLinkedListLink pivotLocation = partition(list, first, last);
recQuickSort(list, first, pivotLocation.back);
recQuickSort(list, pivotLocation.next, last);
}
}
public void quickSort(DoublyLinkedList list)
{
recQuickSort(list, list.first, list.last);
}
}
Main Method
class MergeSortDriver
{
public static void main (String [] args)
{
Employee e1 = new Employee("Grey","Bob",5239);
Employee e2 = new Employee("Smith","Maggie", 9845);
Employee e3 = new Employee("Ocasio","John", 8502);
Employee e4 = new Employee("Yang", "Christina", 4656);
Employee e5 = new Employee("Carpenter","Kimberely", 6798);
Employee e6 = new Employee("Aguilar","Charlie", 5986);
DoublyLinkedList a = new DoublyLinkedList();
Employee A[] = {e1,e2,e3,e4,e5,e6};
a.insert(e1);
a.insert(e2);
a.insert(e3);
a.insert(e4);
a.insert(e5);
a.insert(e6);
a.print();
a.quickSort();
a.print();
}
}
Use this instead of the parameter. Instead of:
public void quickSort(DoublyLinkedList list)
{
recQuickSort(list, list.first, list.last);
}
You can do
public void quickSort()
{
recQuickSort(this, this.first, this.last);
}
This way you are using the instance you are invoking quickSort on, instead of one passed into the quickSort method.
EDIT - Regarding the error mentioned in comments:
The NullPointerException does not have anything to do with whether you use this instead of a parameter. Instead I suspect it has something to do with your while loop around the recursive calls.
while(first != last)
{
DoublyLinkedListLink pivotLocation = partition(list, first, last);
recQuickSort(list, first, pivotLocation.back);
recQuickSort(list, pivotLocation.next, last);
}
Such a while-loop is usually not needed in a recursive solution. You can (kinda) think of your recursion as your loop. So instead of a loop, you should restrict the calls with ifs. It could look something like:
DoublyLinkedListLink pivot = partition(list, first, last);
if(first != pivot && first != pivot.back) {
recQuickSort(list, first, pivot.back);
}
if(last != pivot && last != pivot.next) {
recQuickSort(list, pivot.next, last);
}
Furthermore, you should handle the case when the list is empty. In this case partition will throw a NullPointerException because both first and last would be null.
I would think that fixing these two things would make it work. However, I have not tested it.
Also, try to keep code nicely formatted. Code without consistent formatting (such as indentation) is a pain to work with and look at.
I'm having troubling organizing my list of employees. I just need to organize them according to their employee type (first two letters). Each object starts with the employee code which are the first two letters. This is what I need to separate the position types but for some reason I can't grab them.
Here is the file that I am creating the objects out of and storing them in the arrays.
PW_1234,James,Bond,01/02/10,1,10 PW_1235,John,Brown,02/03/10,2,10.5
PW_1236,Howard,Johnson,03/04/10,3,11
PW_1237,Francis,Themule,04/05/11,4,10.75
PW_1238,Mathew,Lewis,05/06/11,1,12.75
PW_1239,Mark,Bixton,05/13/11,2,13
PW_1242,Sarah,Glover,05/14/11,1,13.75 PW_1245,John,Doe,05/15/11,4,10.5
PW_1245,Mary,Doe,05/15/11,4,10.5
TL_1248,Abel,English,05/16/11,3,16.5,0.01,100,89
TL_1251,Eustis,Clauser,05/17/11,2,16,0.02,100,9
SU_1254,Henry,Hollowman,05/18/11,1,40000,0.01
PW_1240,Luke,Sailor,01/22/12,3,14.5 PW_1243,Jane,Baker,01/23/12,2,14
PW_1243,Jane,Baker,01/23/12,2,14
TL_1246,David,Brief,01/24/12,1,14.75,0.01,100,57
PW_1246,David,Doson,01/24/12,1,14.75
TL_1249,Baker,Anderson,01/25/12,4,11.5,0.01,100,100
TL_1252,Frank,Donson,01/26/12,3,17.5,0.02,100,39
SU_1255,Issac,Asimov,01/27/12,2,43000,0.02
SU_1256,Issac,Shoreman,01/28/12,3,39000,0.01
SU_1257,Issac,Roberts,01/29/12,4,35500,0.01
PW_1241,John,Candy,11/23/13,4,9.5 PW_1244,Kate,Smith,11/24/13,3,15.5
PW_1244,Kate,Handle,11/24/13,3,15.5
TL_1247,Samual,Dempky,11/25/13,2,15,0.01,100,10
TL_1250,Charley,Boman,11/26/13,1,15.75,0.01,100,50
TL_1253,George,Fritzmen,11/27/13,4,12.5,0.02,100,27
Here is the code:
private String makeEmployeeList()
{
String list = "";
for(int i=0; i < employees.length; i++)
{
list += "\n"+employees[i].toString();
if(employees[i]substring(0,2).equals("SU"))
{
list += "\n"+employees[i].toString();
}
}
return list;
}
**Here is how the employees array is created:
private Employee[] employees;
**Here is how everything is loaded into it.
public void loadEmployeesFromFile(String fileName)
{
File inFile = new File(fileName);
if(inFile.exists()) // MAKE SURE FILE EXISTS
{
try
{
BufferedReader inReader = new BufferedReader(new FileReader(inFile));
inReader.mark(32000);
String inLine = inReader.readLine();
//************************************
// Counting rows to set array size
//************************************
int rowCount = 0;
while (inLine != null && !inLine.equals(""))
{
rowCount++;
inLine = inReader.readLine();
}
inReader.reset();
//*******************
// re-reading data
//*******************
this.employees = new Employee[rowCount];
for(int rowIndex = 0;rowIndex < rowCount; rowIndex++)
{
inLine = inReader.readLine();
Scanner employeeScanner = new Scanner(inLine).useDelimiter(",");
String workerType = employeeScanner.next();
String firstName = employeeScanner.next();
String lastName = employeeScanner.next();
String hireDate = employeeScanner.next();
int shift = employeeScanner.nextInt();
if(workerType.substring(0,2).equals("PW"))
{
double pay = employeeScanner.nextDouble();
employees[rowIndex]= new ProductionWorker(workerType, firstName, lastName, hireDate, shift, pay);
}
else if(workerType.substring(0,2).equals("TL"))
{
double pay = employeeScanner.nextDouble();
double bonusRate = employeeScanner.nextDouble();
int reqHours = employeeScanner.nextInt();
int recHours = employeeScanner.nextInt();
employees[rowIndex]= new TeamLeader(workerType, firstName, lastName, hireDate, shift, pay, bonusRate, reqHours, recHours);
}
else if(workerType.substring(0,2).equals("SU"))
{
double salary = employeeScanner.nextDouble();
double bonusRate = employeeScanner.nextDouble();
employees[rowIndex]= new ShiftSupervisor(workerType, firstName, lastName, hireDate, shift, salary, bonusRate );
}
}
return;
}catch(IOException ioe)
{
System.err.print("\nTrouble reading employee file: "+fileName);
}
}
JOptionPane.showMessageDialog(null, "\nFile Name does not exist!\n Process terminating!");
System.exit(0);
}
private String makeEmployeeList(){
StringBuilder sbSU = null;
for(int i=0; i < employees.length; i++)
{
sbSU = new StringBuilder();
if(employees[i].substring(0,2).equals("SU"))
{
sbSU.append(employees[i].toString());
}
}
return sbSU.toString();
}
First of all, you missed a dot after emplyees[i] subsrting
As string is an immutable object, I suggest you use StringBuilder and its append method instead of +=. and use its toString() method to convert StringBuilder to a String. You also need to override your Employees's toString method.
to sort the employees in an array, you need to implements Comparable or Comparator interface so that the Array knows which criteria to use when sorting your employees, in your case it is to compare the employee's type
As you are using JOptionPane you can use html inside to give it format. Make an Employee class and make it's natural order by type, or you can use a Comparator if you don't want to use Comparable
I made a complete example for you.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JOptionPane;
public class Employee implements Comparable<Employee> {
private String type;
private String name;
public Employee(String type, String name) {
super();
this.type = type;
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
public int compareTo(Employee o) {
if (this.type.equals(o.type)) {
return name.compareTo(o.name);
}
return type.compareTo(o.type);
}
public static void main(String[] args) {
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee("CA","John"));
employees.add(new Employee("CA", "Suzy"));
employees.add(new Employee("TA","Malcom"));
employees.add(new Employee("AA","Rose"));
// Sort the list by type as its natural order or use proper Comparator
Collections.sort(employees);
StringBuilder sb = new StringBuilder();
sb.append("<html><table><tr><td>Type</td><td>Name</td></tr>");
for (Employee e : employees) {
sb.append("<tr>");
sb.append("<td> ").append(e.getType()).append("</td>");
sb.append("<td> ").append(e.getName()).append("</td>");
sb.append("</tr>");
}
sb.append("</table></html>");
JOptionPane.showMessageDialog(null, sb);
}
}
Output: