How to find the second largest element in an array of objects - java

I need to know the way to find the second largest element among an array of objects. for eg.
if there is an array of objects of a Book class with attributes like book name, price, in stock quantity
Book[] b=new Book[];
b[0]=new Book("x",200,50);
b[1]=new Book("y",100,44);
b[2]=new Book("z",500,29);
How can we list the book with second largest price along with other attributes like name and in stock quantity

Make a List of Books from it, sort it using Collections.sort and take the element on index 1.
List<Book> booklist = new ArrayList<Book>(Arrays.asList(b));
Collections.sort(booklist, new Comparator<Book>() {
#Override
public int compare(Book o1, Book o2) {
return o2.getPrice() - o1.getPrice();
}
});
if (booklist.size() > 1) {
System.out.println(booklist.get(1));
}

You can loop through this Array to find the largest and with this the second largest Element of the Array. Because the Elements are Objects you have to get the Value that you want to compare from the element with a getter or the variable is public in the objects.
public int getSecondLargest(Object[] obj){
int length = obj.length;
int largest = 0;
int secondLargest = 0;
for(int i = 0; i<length; i++){
if(obj[largest].getValue() <= obj[i].getValue()){
secondLargest = largest;
largst = i;
}
}
return secondLargest;
}

I think you should implements Interface Comparable.
and then use Collections.sort();

Implements a Comparator And sort your array, then pick second element.
class BookPriceComparator implements Comparator<Book> {
#Override
public int compare(Book a, Book b) {
return a.getPrice() - b.getPrice();
}
}
Arrays.sort(bookArr, new BookPriceComparator ());

import java.util.*;
//here you can make changes or you can create your own new class
//to sort book according to pages
class sortPrice implements Comparator<Test> {
public int compare(Test i1, Test i2) {
Integer x = i1.getPrice(), y = i2.getPrice();
return y.compareTo(x); // <--- changed
}
}
// in your case Test class could be Book class
public class Test {
/**
* #param args
*/
int price , page ;
String name;
Test(String n , int p ,int pg){
name=n;
price=p;
page=pg;
}
public String toString(){
return name+" "+price +" "+page ;
}
public String getName(){
return name;
}
public int getPage(){
return page;
}
public int getPrice(){
return price;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Test[] b=new Test[3];
b[0]=new Test("x",200,50);
b[1]=new Test("y",100,44);
b[2]=new Test("z",500,29);
ArrayList<Test> a = new ArrayList<>();
for(int i=0;i<3;i++){
a.add(b[i]);
}
sortPrice s= new sortPrice(); // required to pass as argument to tell
//based on which sorting order you want to sort
Collections.sort(a,s ); //here we are sorting Test(Book) based on price.
System.out.println(a.get(1)); // printing arrayList //<----- changed
}
}

Related

How to join a String array to a int array and sort by number (higher to lower) in Android?

I have two arrays:
int[] sinais = new int[arraySinais.length];
String[] arraySSID = new String[] { };
And I joined them into one array:
String[] arrayScan = new String[arraySinais.length];
for (int i = 0; i < arraySSID.length; i++) {
arrayScan[i] = arraySSID[i] + " " + sinais[i];
}
But now I need to sort this new array by numbers in a decreasing order and put an Image inside ListView depending the numbers, and I do not have any idea how to do this.
you can use create your own object which contains the int and the string and use arraylist to sort
First create your own custom Element (Object) which mainly consist of an int number and a String string.
public class Element implements Comparable<Element>{
private int number;
private String string;
public Element(String string, int number) {
this.number =number;
this.string = string;
}
//create custom constructors if its allowed to define an element without a number or string
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
#Override
public int compareTo(Element e) {
return number - e.number;
}
}
Implement comparable as above to sort depending on the number value, but keep in my mind that your element won't sort stand alone strings.
If you want to sort your list depending on strings if a number doesn't exist use this implementation of comparTo() method:
#Override
public int compareTo(Element e) {
if(e.number != 0) return number - e.number;
return string.compareTo(e.string);
}
While using implement a List of elements and use Collections sort() method and you are good to go:
List<Element> list = new ArrayList<>();
//add Elements
Collections.sort(list);
I used the method below, by Bubble Sort, and solve my problem:
> for (int i = Sinais.length; i >= 1; i--){
> for (int j = 1; j < i; j++){
> if (Sinais[j-1]<Sinais[j]){
> int aux = Sinais[j];
> String aux2 = ArraySSID[j];
> Sinais[j] = Sinais[j-1];
> ArraySSID[j] = ArraySSID[j-1];
> Sinais[j-1] = aux;
> ArraySSID[j-1] = aux2;
> }
> }
> }

What is the most efficient way to simultaneously sort three ArrayLists in Java

I have three ArrayLists. One of Strings - names, and two of Integers - score and picture numbers. I want to sort them simultaneously by the players scores (from highest to lowest). Now i use a simple bubble sort, but i think it will not be efficient when the Lists will be bigger.
This is my code:
public class MyBubbleSort {
public static void bubble_srt(List<Integer> score, List<String> name, List<Integer> pic) {
int n = score.size();
int k;
for (int m = n; m >= 0; m--) {
for (int i = 0; i < n - 1; i++) {
k = i + 1;
if (score.get(i) < score.get(k)) {
swapNumbers(i, k, score, name, pic);
}
}
printNumbers(score);
}
}
private static void swapNumbers(int i, int j, List<Integer> score, List<String> name, List<Integer> pic) {
int temp;
temp = score.get(i);
score.set(i, score.get(j));
score.set(j, temp);
String s;
s = name.get(i);
name.set(i, name.get(j));
name.set(j, s);
int p;
p = pic.get(i);
pic.set(i, pic.get(j));
pic.set(j, p);
}
private static void printNumbers(List<Integer> input) {
for (int i = 0; i < input.size(); i++) {
System.out.print(input.get(i) + ", ");
}
System.out.print("\n");
}
}
Thanks!
Best way would be to create a class containing score, name and pic properties and have a single List of that class, which you sort using Collections.sort and a Comparator that compares two instances of your class according to the score property.
Bubble sort is in-efficient compared to other sorting algorithms (merge sort, quick sort), and there's no need to implement a sort algorithm yourself, since the standard Java packages already do that for you.
First create a PlayerInfo class as follows:
package test;
public class PlayerInfo {
private String name;
private Integer score;
private Integer pictureId;
public PlayerInfo(final String name, final Integer score, final Integer pictureId) {
this.name = name;
this.score = score;
this.pictureId = pictureId;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public Integer getScore() {
return this.score;
}
public void setScore(final Integer score) {
this.score = score;
}
public Integer getPictureId() {
return this.pictureId;
}
public void setPictureId(final Integer pictureId) {
this.pictureId = pictureId;
}
#Override
public String toString() {
return this.name + ":" + this.score + ":" + this.pictureId;
}
}
Second create a PlayerInfo Comparator. Here we create a ScoreBasedComparator (as per your request, but you can create other comparators as well to fit your specific needs):
package test;
import java.util.Comparator;
public class ScoreBasedComparator implements Comparator<PlayerInfo> {
#Override
public int compare(final PlayerInfo playerInfo1, final PlayerInfo playerInfo2) {
return playerInfo1.getScore().compareTo(playerInfo2.getScore());
}
}
Finally, you can sort your List of PlayerInfo instances, using Collections.sort(<your collection>, <your comparator>) as follows:
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Runner {
public static void main(final String[] args) {
List<PlayerInfo> playerInfos = new ArrayList<PlayerInfo>();
playerInfos.add(new PlayerInfo("A", 123, 1));
playerInfos.add(new PlayerInfo("B", 1, 2));
playerInfos.add(new PlayerInfo("C", 23, 3));
playerInfos.add(new PlayerInfo("D", 300, 4));
Collections.sort(playerInfos, new ScoreBasedComparator());
System.out.println(Arrays.toString(playerInfos.toArray()));
}
}
Running this small program will output the following line:
[B:1:2, C:23:3, A:123:1, D:300:4]
As you can see your collection was unsorted at creation time but is printed sorted by score.
Hope this helps.
If the goal here is to sort three arrays according to one of the arrays, without resorting to combining the arrays into a common class, then a fourth array of indices, 0 to size-1 can be created, then the array of indices is sorted according to one of the arrays (using a built in sort and custom compare). Then all three arrays are reordered according to the array of sorted indices. I don't know if Java has a built in reorder function. C example to reorder 3 arrays, A,B,C according to sorted array of indices I, with time complexity of O(n) (linear, every store places a value in it's ordered position). I is reverted back to 0 to n-1.
// reorder A,B,C in place according to I
// tA,tB,tC are temps
for(i = 0; i < n; i++){
if(i != I[i]){
tA = A[i];
tB = B[i];
tC = C[i];
k = i;
while(i != (j = I[k])){
A[k] = A[j];
B[k] = B[j];
C[k] = C[j];
I[k] = k;
k = j;
}
A[k] = tA;
B[k] = tB;
C[k] = tC;
I[k] = k;
}
}

issue with Arrays.asList()

I have a very simple program and I just need to check an array for a value in it.
I have a class called bulkBean. this is it.
public class bulkBean {
private int installmentNo;
private double amount;
public int getInstallmentNo() {
return installmentNo;
}
public void setInstallmentNo(int installmentNo) {
this.installmentNo = installmentNo;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
Now I have an array of this bulkBean type in my program, this is my program.
import java.util.Arrays;
public class test {
public static boolean scan_bulkList(bulkBean[] bulkList, int i) {
int[] arr = new int[bulkList.length];
for(int x=0;x<bulkList.length;x++){
arr[x] = bulkList[x].getInstallmentNo();
}
for(int j = 0; j< arr.length ;j++){
System.out.println("INFO: array "+j+" = "+arr[j]);
}
if (Arrays.asList(arr).contains(i) == true) {
return true;
} else {
return false;
}
}
public static void main(String[] arg){
bulkBean bb1 = new bulkBean();
bb1.setInstallmentNo(1);
bb1.setAmount(5500);
bulkBean bb2 = new bulkBean();
bb2.setInstallmentNo(2);
bb2.setAmount(4520);
bulkBean[] bulkArray = new bulkBean[2];
bulkArray[0] = bb1;
bulkArray[1] = bb2;
boolean a = scan_bulkList(bulkArray,1);
System.out.println("val = "+a);
}
}
I create 2 instances of bulk bean and I set values to them. Then I added those two instances to an array. Then I pass that array to the method to check for a value(also given as a parameter. In this case it is 1.). If the array contains that value, it should return true, otherwise false.
whatever value I enter, it return false.
Why do I get this issue?
Arrays.asList() returns a List which has a single element - an array. So, you are actually comparing against an array. You need to compare against each value in the array.
As TheListMind told, Arrays.asList() taken on an int[] gives you a list containing the array.
Personally, I would construct directly the List instead of constructing the array, or even better (no need of array instanciation), test while iterating the bulk array :
for(int x=0;x<bulkList.length;x++){
if (bulkList[x].getInstallmentNo() == i){
return true;
}
}
return false;
The mistake you made here is , you created the int array which must be Integer array because Arrays.asList().contains(Object o); makes the input parameter also Integer(Integer i). int is not an object Integer is the object. Hope it will work.
int[] arr = new int[bulkList.length];
change to:
Integer[] arr = new Integer[bulkList.length];
Change the method as below to avoid complications:
public static boolean scan_bulkList(bulkBean[] bulkList, int i) {
int[] arr = new int[bulkList.length];
for(int x=0;x<bulkList.length;x++){
arr[x] = bulkList[x].getInstallmentNo();
if (bulkList[x].getInstallmentNo()==i) {
return true;
}
}
return false;
}

How to alter a bubble sort from numeric to alphabetical?

I am using an ArrayList with book titles and book ratings. How can I change this code to make the bubble sort for alphabetical instead of numeric?
System.out.println("\r" + "In order by rating");
for (int out = 0; out < bookList.size(); out++) {
for (int in = 0; in < bookList.size() - 1; in++)
if (bookList.get(in).getRating() < bookList.get(in + 1).getRating()) {
Book temp = bookList.get(in);
bookList.set(in, bookList.get(in+1));
bookList.set(in+1, temp);
}
System.out.println(videoList.get(out).getTitle() + " " + videoList.get(out).getRating());
}
}
My other classes are below.
Book
public class Book {
String title;
int rating;
public Book(String pTitle, int pRating) {
title = pTitle;
rating = pRating;
}
public String getTitle() {
return title;
}
public int getRating() {
return rating;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public void setRating(int newRating) {
rating = newRating;
}
}
Library
import java.util.ArrayList;
public class Library {
public static void main (String [] args) {
ArrayList<Book> bookList = new ArrayList<Book>();
Book b1 = new Book ("Huckleberry Finn", 5);
Book b2 = new Book ("The Great Gadsby", 2);
Book b3 = new Book ("Harry Potter", 3);
Book b4 = new Book ("Animal Farm", 4);
Book b5 = new Book ("The Mist", 1);
bookList.add(b1);
bookList.add(b2);
bookList.add(b3);
bookList.add(b4);
bookList.add(b5);
System.out.println("Original sequence");
for (int cnt = 0; cnt < videoList.size(); cnt++) {
System.out.println(bookList.get(cnt).getTitle() + " " + bookList.get(cnt).getRating());
}
}
}
Is there a way to alter the code in the algorithm class to display the bookList sorted by Title?
You can't use < directly on two Strings, but you can use compareTo.
if (bookList.get(in).getTitle().compareTo(bookList.get(in + 1).getTitle()) < 0) { ...
If s1 and s2 are strings, s1.compareTo(s2) returns a negative value if s1 is lexicographically less than s2, a positive value if s1 is greater, and 0 if the two strings are equal.
For your class Book make it implement Comparable. You'll have to create some methods in your Book class in order to compile. Implement them according to the Java API then you can just throw them into a TreeSet<Book> and it will be sorted.
Edit:
I realize this doesn't directly answer your question, but it would be a more Java solution.
I think change your code :
if (bookList.get(in).getRating() < bookList.get(in + 1).getRating())
to
if (bookList.get(in).getTitle().compareTo(bookList.get(in + 1).getTitle()<0)
would be OK.
But,why dont you implement different Comparators and use it like this: Collections.sort(bookList,yourComparator)
something like this:
public static void main(String[] args) {
List<Book> bookList = new ArrayList<Book>();
Collections.sort(bookList, new TitleComparator());
Collections.sort(bookList, new RatingComparator());
}
static class TitleComparator implements Comparator<Book> {
#Override
public int compare(Book o1, Book o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
}
static class RatingComparator implements Comparator<Book> {
#Override
public int compare(Book o1, Book o2) {
return o1.getRating() - o2.getRating();
}
}
To implement bubble-sort for any type of Object, in that case Book, implements in your object class the interface Comparable and override the methode compareTo to define your desired handling.
The method should return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
As stated in the javadoc :
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
In your case, the compareto method is already implemented in the String class so you can directly use it on the book's title.
Your validation would then look like this :
if (bookList.get(in).getTitle().compareTo(bookList.get(in + 1).getTitle()) < 0)

How to add items to arraylist and modify a feature

I am trying to add items to my array list with an action listener on a pop up window. You can see the action listener here. The problem that I am now having is I do not know how to add the inputs to my array list. Part of this problem is that I need to set my item number to 1 higher than the highest in my list. My array list is named as such:
private static ArrayList<InventoryItem> inventory = new ArrayList<>();
and the class for InventoryItem looks like this:
public class InventoryItem { //Delcare variables below
DecimalFormat formatted = new DecimalFormat("#,###.00");//set up decimal format for displaying 12.34 type values
String itemName;
int itemNumber;
public String getItemName() {
return itemName;
}
public int getItemNumber(){
return itemNumber;
}
int inStock;
double unitPrice;
double value;
double restockingFee;
double inventoryValue;
public InventoryItem(String itemName, int itemNumber, int inStock, double unitPrice) { //declare variables for this class
this.itemName = itemName;
this.itemNumber = itemNumber;
this.inStock = inStock;
this.unitPrice = unitPrice;
stockValue(); //call stock value
}
}
So my question is two parts. The first is how do I get my itemNumber to increment to 1 higher than the highest? Do I simply do a bubble sort to find the highest? And the second part is how do I get it to add all items, including this incremented itemNumber, into my original arraylist?
Note
If needed I can paste my code in it's entirety on pastebin as it is somewhat large.
EDIT: Per #Prabhakaran I have added some code and I am almost there. I have almost gotten this to work, however when I start to look through my list I do not see the added feature so how can I be sure that I am actually adding it?
String newItemName = String.valueOf(xField);
String text1 = yField.getText();
String newInventoryAmount = String.valueOf(text1);
int newNumber = Integer.parseInt(newInventoryAmount);
String text2 = zField.getText();
String newUnitPrice = String.valueOf(text2);
double newPrice = Double.parseDouble(newUnitPrice);
for (int i = 0; i >= inventory.size(); i++) {
inventory.get(inventory.size() ).getItemNumber();
int newItemNumber;
newItemNumber = i + 1;
InventoryItem item = new InventoryItem(newItemName, newItemNumber, newNumber, newPrice);
inventory.add(item);
What am I missing here? Shouldn't this simply add an item to my arraylist? I know it must be something really easy, I just can't seem to figure it out.
Here is my sort by ItemName:
static ArrayList sortInventory(ArrayList<InventoryItem> unsorted) {
ArrayList<InventoryItem> sorted = new ArrayList<>(); //create new array list to sort
InventoryItem alpha = null;
int lowestIndex = **-1**;
while (unsorted.size() > 0) { //while my unsorted array is less than 0 do the following
for (int i = 0; i < unsorted.size(); i++) { //increment through
if (alpha == null) {
alpha = unsorted.get(i); //get the next line in the inventoryItem array
lowestIndex = i;
} else if (unsorted.get(i).itemName.compareToIgnoreCase(alpha.itemName) < 0) { //compare items to determine which has a higher value
alpha = unsorted.get(i);
lowestIndex = i;
}
}
sorted.add(alpha); //reset the index so it will loop until there are no more items in the unsorted array
unsorted.remove(lowestIndex);
alpha = null;
lowestIndex = **0**;
}
return sorted; //return the sorted arraylist
}
EDIT: Corrected the lowestIndex and it goes good as gold.
Do like this
private static ArrayList<InventoryItem> inventory = new ArrayList<>();
String newItemName = String.valueOf(xField);
String newInventoryNumber = String.valueOf(yField);
int newNumber = Integer.parseInt(newInventoryNumber);
String newUnitPrice = String.valueOf(zField);
double newPrice = Double.parseDouble(newUnitPrice);
InventoryItem item =new InventoryItem(newItemName , newInventoryNumber , newNumber , newUnitPrice ) ;
inventory.add(item);
update
class SimpleComparator implements Comparator<InventoryItem> {
#Override
public int compare(InventoryItem o1, InventoryItem o2) {
return new Integer(o1.getItemNumber()).compareTo(o2.getItemNumber());
}
}
//Sorting based on the itemNumber.
Collections.sort(inventory,new SimpleComparator());
int newItemNumber = inventory.get(inventory.size() - 1).getItemNumber();
newItemNumber ++;
You could create your own ArrayList with Observer support:
public class InventoryItemArrayList extends ArrayList {
private static final long serialVersionUID = 4550719458611714650L;
private List listeners = new ArrayList();
public void addInventoryItemAddedListener(InventoryItemAddedListener listener) {
this.listeners.add(listener);
}
#Override
public boolean add(InventoryItem e) {
boolean add = super.add(e);
fireInventoryItemAdded(e);
return add;
}
private void fireInventoryItemAdded(InventoryItem e) {
for (InventoryItemAddedListener element : listeners) {
element.inventoryItemAdd(e);
}
}
#Override
public void add(int index, InventoryItem element) {
super.add(index, element);
fireInventoryItemAdded(element);
}
#Override
public boolean addAll(Collection c) {
boolean addAll = super.addAll(c);
fireInventoryItemAdded(c);
return addAll;
}
private void fireInventoryItemAdded(Collection c) {
for (InventoryItem inventoryItem : c) {
fireInventoryItemAdded(inventoryItem);
}
}
#Override
public boolean addAll(int index, Collection c) {
boolean addAll = super.addAll(index, c);
fireInventoryItemAdded(c);
return addAll;
}
}

Categories