QuickSort for ArrayList<Object> - java

I seem to be having some problems witn my quicksort method. I am trying to sort an ArrayList of objects using my quicksort method. I am using the Apache POI library to extract data from an excel file and I am adding this data to my arraylist. I have confirmed that my arraylist is not empty by printing out the arraylist before applying the quicksort method.
My problem seems to be that after passing in my arraylist of objects it gets reset to null and the size of the arraylist becomes 0. I got a java IndexOutOfBounds Exception within my quicksort method while trying get an object from the arraylist. Any help would be appreciated, thanks !
Here is my main class :
EDIT I solved my problem using the given solution below, but I still don't understand why my quicksort function doesn't work. I would appreciate it if someone could look at the quicksort function and tell me where I am going wrong. Thanks !
public class Test {
private static ArrayList<Object> incom = new ArrayList<Object>();
private static int period;
private static String termination = "yes";
private static int pivotVal;
private static ArrayList<String> treatment_name = new ArrayList();
private static ArrayList<Integer> treatment_cstart = new ArrayList();
private static ArrayList<Integer> treatment_cend = new ArrayList();
private static ArrayList<Integer> treatment_cost = new ArrayList();
private static ArrayList<Integer> bridge_part = new ArrayList();
private static ArrayList<Integer> budget = new ArrayList();
private static Scanner input = new Scanner(System.in);
private static Scanner alt = new Scanner(System.in).useDelimiter("\n");
public static void main(String[] args)
{
processFile();
}
public static void processFile(){
try {
POIFSFileSystem fs =
new POIFSFileSystem(new FileInputStream("Book2.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet =wb.getSheet("Table0");
RowProcessor ip = IncomeProcessor.getInstance();
Object [] incomes = ip.process(sheet);
for (int i=0; i<incomes.length; i++)
incom.add(incomes[i]);
for (int i=0; i<incom.size(); i++)
{
Income income = (Income)incom.get(i);
System.out.println(income.getBridgeID() + " " + income.getDeckState());
}
incom = quicksort(incom);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static ArrayList<Object> quicksort(ArrayList<Object> income){
int pivot = income.size()/2;
int samePivotVal = 0;
ArrayList<Object> greater = new ArrayList<Object>();
ArrayList<Object> lesser = new ArrayList<Object>();
Income pivotIncome = (Income) income.get(pivot);
pivotVal = pivotIncome.getDeckState();
Income in;
for(int i=0; i<income.size() ;i++){
in = (Income)income.get(i);
if(in.getDeckState() > pivotVal)
greater.add(in);
else if(in.getDeckState() < pivotVal)
lesser.add(in);
else
samePivotVal++;
}
lesser = quicksort(lesser);
for(int i=0; i<samePivotVal; i++)
lesser.add(pivotIncome);
greater = quicksort(greater);
ArrayList<Object> sorted = new ArrayList<Object>();
for(Object result : lesser)
sorted.add(result);
for(Object result : greater)
sorted.add(result);
return sorted;
}
}

It will be a lot easier (and better) if you use Java's builtin sorting methods.
public static void processFile(){
//...
Collections.sort(incom, new IncomComparator());
//...
}
class IncomComparator implements Comparator<Object> {
#Override
public int compare(Object o1, Object o2) {
/* compare logic goes here
return a negative number when o1 < o2
a positive number when o1 > o2
0 when o1 == o2
*/
return 0;
}
}
or in a more simple way
public static void processFile(){
//...
Collections.sort(incom, new Comparator<Object>() {
#Override
public int compare(Object o1, Object o2) {
/* compare logic goes here
return a negative number when o1 < o2
a positive number when o1 > o2
0 when o1 == o2
*/
return 0;
}
});
//...
}
You can see some more examples here.

Related

How to retrieve element from ArrayList containing long array

How to retrieve element from ArrayList<long[]>?
I wrote like this:
ArrayList<long []> dp=new ArrayList<>();
//m is no of rows in Arraylist
for(int i=0;i<m;i++){
dp.add(new long[n]); //n is length of each long array
//so I created array of m row n column
}
Now how to get each element?
every element in that list is an array... so you need to carefully add those by:
using anonymous arrays new long[] { 1L, 2L, 3L }
or especifying the size using the new keyword new long[5]
public static void main(String[] args) throws Exception {
ArrayList<long[]> dp = new ArrayList<>();
// add 3 arrays
for (int i = 0; i < 3; i++) {
dp.add(new long[] { 1L, 2L, 3L });
}
// add a new array of size 5
dp.add(new long[5]); //all are by defaul 0
// get the info from array
for (long[] ls : dp) {
for (long l : ls) {
System.out.println("long:" + l);
}
System.out.println("next element in the list");
}
}
You get the arrays the same way you get anything from an ArrayList. For example, to get the tenth long[] stored in the ArrayList, you'd use the get method:
long[] tenthArray = dp.get(9);
You could also have an ArrayList of objetcs that contain an array of longs inside. But the problem so far with your code is that you are not putting any values in each long array.
public class NewClass {
private static class MyObject {
private long []v;
public MyObject(int n) {
v = new long[n];
}
#Override
public String toString() {
String x = "";
for (int i = 0; i < v.length; i++) {
x += v[i] + " ";
}
return x;
}
}
public static void main(String[] args) {
ArrayList<MyObject> dp = new ArrayList();
int m = 3;
int n = 5;
for (int i = 0; i < m; i++) {
dp.add(new MyObject(n));
}
for (MyObject ls : dp) {
System.out.println(ls);
}
}
}

Casting from ArrayList<Object> to my own class

I have two ArrayLists, teamList1 and teamList2, which each contain five Team objects. I'm comparing those contents to each other in one of my methods. I must pass in these two ArrayLists as a single 2-element simple array argument, Objects[], into the method. I'm getting a compiler error because I'm struggling with casting from type Objects into type Team. In other words, changing from a Collection to a simple array back to a Collection is giving me an error. Anyone have a tip on my casting error?
CommonElements.java
package test;
import javax.swing.*;
import java.util.*;
public class CommonElements {
List<Comparable> teamList1 = new ArrayList<Comparable>();
List<Comparable> teamList2 = new ArrayList<Comparable>();
List<Comparable> commonList = new ArrayList<Comparable>();
Object[] listCollection = new Object[2];
int comparisonCount;
public static void main(String[] args) {
new CommonElements();
}
public CommonElements() {
comparisonCount = 0;
Team a = new Team("Boston");
Team b = new Team("Seattle");
Team c = new Team("Newark");
Team d = new Team("Houston");
Team e = new Team("Salt Lske City");
teamList1.add(a);
teamList1.add(b);
teamList1.add(c);
teamList1.add(d);
teamList1.add(e);
Team f = new Team("Seattle");
Team g = new Team("Nashville");
Team h = new Team("St. Louis");
Team i = new Team("New York");
Team j = new Team("Boston");
teamList2.add(f);
teamList2.add(g);
teamList2.add(h);
teamList2.add(i);
teamList2.add(j);
listCollection[0] = teamList1;
listCollection[1] = teamList2;
findCommonElements(listCollection);
System.out.println(comparisonCount);
}
public Comparable[] findCommonElements(Object[] collections)
{
ArrayList<Object> objectTeam1 = new ArrayList<Object>(Arrays.asList(collections[0]));
ArrayList<Object> objectTeam2 = new ArrayList<Object>(Arrays.asList(collections[1]));
ArrayList<Team> team1 = (ArrayList)objectTeam1;
ArrayList<Team> team2 = (ArrayList)objectTeam2;
Team[] commonList = new Team[5];
int i = 0;
for(Team x:team1)
{
for(Team y:team2)
{
comparisonCount++;
if(x.compareTo(y) == 0)
{
commonList[i] = x;
System.out.println(commonList[i].teamName);
i++;
break; /*to ensure it looks for only one match per entry*/
}
}
}
return commonList;
}
public int getComparisons()
{
return comparisonCount;
}
}
Team.java
package test;
public class Team implements Comparable<Team> {
String teamName = new String();
public void setName ( String n ) {
teamName = n;
}
public Team(String n) {
setName(n);
}
public int compareTo(Team x)
{
if(this.teamName.equals(x.teamName))
{
return 0;
}
else
{
return -1;
}
}
}
That is a very unfortunate and odd way of passing the arguments, but anyway, to make it work, you can do:
#SuppressWarnings("unchecked")
ArrayList<Team> team1 = (ArrayList<Team>)collections[0];
#SuppressWarnings("unchecked")
ArrayList<Team> team2 = (ArrayList<Team>)collections[1];
Your existing code was taking each ArrayList, putting it into a one element array, wrapping that array as a list, creating an ArrayList from it, and trying to view the ArrayList<ArrayList<Team>> as an ArrayList<Team>.
A few other things I see... you don't need to assign these to variables if you're only using them to add to the list:
Team a = new Team("Boston");
...
teamList1.add(a);
You can simply do:
teamList1.add(new Team("Boston"));
You don't need to create the listCollection array separately, because you can create it inline when passing the arguments:
findCommonElements(new Object[] { teamList1, teamList2 });
In your Team class, this:
String teamName = new String();
Should simply be:
String teamName;
In your compareTo method:
public int compareTo(Team x)
{
if(this.teamName.equals(x.teamName))
{
return 0;
}
else
{
return -1;
}
}
That should be:
public int compareTo(Team x)
{
return teamName.compareTo(x.teamName);
}
which is shorter, and honors the compareTo requirement that sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.

Java - Sorting an ArrayList

I am working on a program where I have to count the frequency of food items in a file in order to sort them in descending order.
For example: if my file has ( pizza, ice_cream, pasta, pizza )
I want my program to print something similar to this:
1 ice_cream
1 pasta
2 pizza
I am using a bubble sort algorithm but it seems that I am missing something for this algorithm to work. Any help will be greatly appreciated!
Within class Listabc, I have two local variables and a method called "compareTo."
class Listabc {
int count = 1;
String item;
int compareTo(Listabc listabc) {
return 0;
}
}
Within my main method, I have a bubble sort algorithm to sort the food items in a descending order
public class MainMethod {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new BufferedReader(new FileReader("file.txt")));
List<Listabc> lists = new ArrayList<Listabc>();
for (int a = 0; a < lists.size() - 1; ++a) {
for (int b = a + 1; b < lists.size(); b++) {
if ((lists.get(b)).compareTo(lists.get(a)) > 0) {
Listabc temp = lists.get(a);
lists.set(a, lists.get(b));
lists.set(b, temp);
}
}
System.out.println(lists.get(a));
}
}
}
Your implementation of compareTo method is broken. You need to change it by applying a real comparison:
int compareTo(Listabc listabc) {
return 0; //this means every element is "similar" to another
}
Here's an example about comparing the elements by the item field:
int compareTo(Listabc listabc) {
return this.item.compareTo(listabc.item);
}
If you make Listabc implement comparable you can just call Collections.sort(lists)
Below program will sort the list using Collections.sort
public class SortMap {
public static void main(String[] args) {
Map<String, Integer> t = new HashMap<String, Integer>();
Scanner sc = null;
try {
sc = new Scanner(new File("foodlist.txt"));
while (sc.hasNext()) {
String item = sc.next();
if (t.get(item) != null) {
Integer count = t.get(item);
t.put(item,++count);
} else {
t.put(item, 1);
}
}
Set<Map.Entry<String, Integer>> mp = t.entrySet();
List<Map.Entry<String, Integer>> ll = new ArrayList<Map.Entry<String,Integer>>(mp);
Collections.sort(ll, new SortMap.ValueComparator());
System.out.println(ll);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
sc.close();
}
}
static class ValueComparator implements Comparator<Map.Entry<String, Integer>> {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
}
}

how to iterate through an array list of class type

I have two classes A and B. I want to access an array list in A from B. The array list is of class C type, which stores objects(packets). I would like to know if there is any way to iterate through the list and get specific data from each packet.
public class PcapStream
{
PcapParser objPcapParser = new PcapParser();
PcapDef numPackets = new PcapDef();
int listSize = numPackets.getMaxPackets();
public void findStream()
{
final ListIterator<PcapDef> packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(final int i=0; i<=listSize;i++)
{
I started off with something like this. Not sure how it works. Class B is PcapStream, Class A is PcapParser, Class C is PcapDef
ListIterator packetIterator = objPcapParser.packet_list.listIterator();
while(packetIterator.hasNext())
{
for(int i=0; i<listSize; i++ )
{
PcapDef packet1 = (PcapDef) packetIterator.next();
PcapDef packet2 = packetIterator; //here I would like to get the 2nd object from the list, not sure how to get that at this point.
}
}
public int compare(final PcapDef packet1, final PcapDef packet2)
{
return 0;
}
I'm still working on it. At this point this is what I have
public void findStream()
{
try
{
for(int i=0;i<listSize;i++)
{
final List <PcapDef> list = new ArrayList<PcapDef>();
final PcapDef packet1 = objPcapParser.packet_list.get(i);
checkPackets(packet1, list, i);
}
}
catch(final IndexOutOfBoundsException e)
{
System.out.println("Exception : " + e);
}
final Set packetSet = Stream.entrySet();
final Iterator setIterator = packetSet.iterator();
while(setIterator.hasNext())
{
final Map.Entry packetEntry = (Map.Entry) setIterator.next();
System.out.print(packetEntry.getKey() + ": ");
System.out.println(packetEntry.getValue());
}
}
private void checkPackets(final PcapDef packet1, final List<PcapDef> list, final int i)
{
for(int j=1;j<listSize && j!=i;j++)
{
final PcapDef packet2 = objPcapParser.packet_list.get(j);
final int value = compare(packet1,packet2);
if(value == 0)
{
list.add(packet1);
list.add(packet2);
checkPackets(packet2, list, i);
}
else
{
Stream.put(i,list); //add list to hashmap
}
}
}
#Override
public int compare(final PcapDef packet1, final PcapDef packet2)
{
final String header1 = packet1.getHeader();
final String header2 = packet2.getHeader();
final String src_port1 = packet1.getSrc_port();
final String dst_port2 = packet2.getDst_port();
final String src_port2 = packet2.getSrc_port();
final String dst_port1 = packet1.getDst_port();
System.out.println(header1 + header2);
int flag = 1;
try{
if(header1.equalsIgnoreCase(header2))
{
if((src_port1.substring(10).equalsIgnoreCase(dst_port2.substring(10))) && (src_port2.substring(10).equalsIgnoreCase(dst_port1.substring(10)) )
{
flag = 0;
return flag;
}
}
}
#Andy This is what I wrote so far. Problems I'm facing: Duplicates are being generated and hashmap entries are not continuous, I mean like index 0,1,2.. instead few locations are empty. Due to this if I give very large files as input to my program it is throwing me an indexoutofboundsexception. I'm a beginner and trying my best. Kindly, help.
You can use the Iterator.next() method to get the next list member. Each call to next() advances to the next list member.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
...
}
EDIT:
And you can use the Iterator.get(int) method to get a list member by index.
while(packetIterator.hasNext())
{
PCapDef packet = packetIterator.next();
for(int i=0; i<listSize; i++ )
{
PcapDef packet2 = objPcapParser.packet_list.get( i )
...
}
}

Adding Multiple Values in ArrayList at a single index

I have a double ArrayList in java like this.
List<double[]> values = new ArrayList<double[]>(2);
Now what I want to do is to add 5 values in zero index of list and 5 values in index one through looping.
The zeroth index would have values {100,100,100,100,100}
The index 1 would have values {50,35,25,45,65}
and all of these values are stored in a double array in following order
double[] values = {100,50,100,35,100,25,100,45,100,65}
How can i do it?
#Ahamed has a point, but if you're insisting on using lists so you can have three arraylist like this:
ArrayList<Integer> first = new ArrayList<Integer>(Arrays.AsList(100,100,100,100,100));
ArrayList<Integer> second = new ArrayList<Integer>(Arrays.AsList(50,35,25,45,65));
ArrayList<Integer> third = new ArrayList<Integer>();
for(int i = 0; i < first.size(); i++) {
third.add(first.get(i));
third.add(second.get(i));
}
Edit:
If you have those values on your list that below:
List<double[]> values = new ArrayList<double[]>(2);
what you want to do is combine them, right? You can try something like this:
(I assume that both array are same sized, otherwise you need to use two for statement)
ArrayList<Double> yourArray = new ArrayList<Double>();
for(int i = 0; i < values.get(0).length; i++) {
yourArray.add(values.get(0)[i]);
yourArray.add(values.get(1)[i]);
}
How about
First adding your desired result as arraylist and
and convert to double array as you want.
Try like this..
import java.util.ArrayList;
import java.util.List;
public class ArrayTest {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Your Prepared data.
List<double[]> values = new ArrayList<double[]>(2);
double[] element1 = new double[] { 100, 100, 100, 100, 100 };
double[] element2 = new double[] { 50, 35, 25, 45, 65 };
values.add(element1);
values.add(element2);
// Add the result to arraylist.
List<Double> temp = new ArrayList<Double>();
for(int j=0;j<values.size(); j++) {
for (int i = 0; i < values.get(0).length; i++) {
temp.add(values.get(0)[i]);
temp.add(values.get(1)[i]);
}
}
// Convert arraylist to int[].
Double[] result = temp.toArray(new Double[temp.size()]);
double[] finalResult = new double[result.length]; // This hold final result.
for (int i = 0; i < result.length; i++) {
finalResult[i] = result[i].doubleValue();
}
for (int i = 0; i < finalResult.length; i++) {
System.out.println(finalResult[i]);
}
}
}
ArrayList<ArrayList> arrObjList = new ArrayList<ArrayList>();
ArrayList<Double> arrObjInner1= new ArrayList<Double>();
arrObjInner1.add(100);
arrObjInner1.add(100);
arrObjInner1.add(100);
arrObjInner1.add(100);
arrObjList.add(arrObjInner1);
You can have as many ArrayList inside the arrObjList. I hope this will help you.
create simple method to do that for you:
public void addMulti(String[] strings,List list){
for (int i = 0; i < strings.length; i++) {
list.add(strings[i]);
}
}
Then you can create
String[] wrong ={"1","2","3","4","5","6"};
and add it with this method to your list.
Use two dimensional array instead. For instance, int values[][] = new int[2][5]; Arrays are faster, when you are not manipulating much.
import java.util.*;
public class HelloWorld{
public static void main(String []args){
List<String> threadSafeList = new ArrayList<String>();
threadSafeList.add("A");
threadSafeList.add("D");
threadSafeList.add("F");
Set<String> threadSafeList1 = new TreeSet<String>();
threadSafeList1.add("B");
threadSafeList1.add("C");
threadSafeList1.add("E");
threadSafeList1.addAll(threadSafeList);
List mainList = new ArrayList();
mainList.addAll(Arrays.asList(threadSafeList1));
Iterator<String> mainList1 = mainList.iterator();
while(mainList1.hasNext()){
System.out.printf("total : %s %n", mainList1.next());
}
}
}
You can pass an object which is refering to all the values at a particular index.
import java.util.ArrayList;
public class HelloWorld{
public static void main(String []args){
ArrayList<connect> a=new ArrayList<connect>();
a.add(new connect(100,100,100,100,100));
System.out.println(a.get(0).p1);
System.out.println(a.get(0).p2);
System.out.println(a.get(0).p3);
}
}
class connect
{
int p1,p2,p3,p4,p5;
connect(int a,int b,int c,int d,int e)
{
this.p1=a;
this.p2=b;
this.p3=c;
this.p4=d;
this.p5=e;
}
}
Later to get a particular value at a specific index, you can do this:
a.get(0).p1;
a.get(0).p2;
a.get(0).p3;.............
and so on.

Categories