Sorting ArrayList of arraylist<integer> - sorting

I have the following ArrayList>. I need to sort this ArrayList by the size of arrayLists inside it. How can this be done?
Thank you!

Write Comparator for and use sort method :-
import java.util.*;
class ListComparator implements Comparator{
public int Compare(Object o1,Object o2){
ArrayList s1=(ArrayList)o1;
ArrayList s2=(ArrayList)o2;
if(s1.size()==s2.size())
return 0;
else if(s1.size()>s2.size())
return 1;
else
return -1;
}
}
Assuming you ArrayList is variable name myList.
Collections.sort(myList, new ListComparator());
Refer this link to understand the concept in java

import java.util.*;
class Details {
public static void main(String args[]){
ArrayList<Integer> listofcountries = new ArrayList<Integer>();
listofcountries.add(89);
listofcountries.add(5);
listofcountries.add(3);
listofcountries.add(9);
/*Unsorted List*/
System.out.println("Before Sorting:");
for(int counter: listofcountries){
System.out.println(counter);
}
/* Sort statement*/
Collections.sort(listofcountries);
/* Sorted List*/
System.out.println("After Sorting:");
for(int counter: listofcountries){
System.out.println(counter);
}
}
}``
Use this code work. This code Work Correct

Related

How to use generics that implements comparable

I am very confused about something in java. So the project I was given is write stacks in java, and the program begins with public class Stack<T extends Comparable<? super T>>. However, when trying to run it in my testing program, no matter the kind of Object I throw at it (Integer, String), it all return the error Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable. My question is how does this sort of generics that implement generic T but also extends Comparable work, and why String still returned the error message (I thought String already implemented Comparable<String>?). Thanks in advance for taking the time to read the question! Here is the rough outline of the code:
public class Stack <T extends Comparable<? super T>>{
private T[] arr;
private int ptr;
private int size;
public Stack(){
this.size = 20;
arr = (T[]) new Object[size];
ptr = -1;
}
public boolean push(T element){
try {
arr[ptr+1] = element;
ptr++;
return true;
}
catch (Exception e) {
return false;
}
}
public T[] toArray(){
return arr;
}
}
I got this error from creating a JUnit testing class, with the implementation of something like:
import static org.junit.Assert.assertEquals;
public class StackTester{
#Test
public void testPush(){
Stack<String> st = new Stack<String>();
for (int i = 0; i < 5; i++){
String var = new Integer(i).toString();
st.push(var);
}
assertEquals(new Integer[]{"3","4","5"}, st.toArray());
}
}
public class StackTester{
#Test
public void testPush(){
Stack<String> st = new Stack<String>();
//normal case
for (int i = 0; i < 5; i++){
String var = new Integer(i).toString();
st.push(var);
}
assertEquals(new Integer[]{3,4,5}, st.toArray());
}
}
Also, I have not added a compareTo method as I don't know what it should compare to, and I don't think there's a particular use case for adding that method. I should add that the goal of this project is to use stacks to manipulate Strings (such as going from infix to postfix).
P.S: I would also mention that I don't really need to compare stacks in my project, which is why the stack class itself is not implementing the Comparable interface.

Counting sort iterating from start

I have seen other questions on SO asking why the last iteration in counting sort, where we place elements on the sorted array cannot start from the start. The reason is that that way the sort algorithm loses its stability.
But what if we reversed the count also? Instead of counting the no of elements present before a specific element, what if we count the no of elements present after that specific element? I have implemented it like the following.
public class TestCountSort {
public static void main(String[] args) {
Element[] arr=new Element[]{new Element("One",1),new Element("Three",2),new Element("Two",1)};
System.out.println("Array before - "+Arrays.toString(arr));
countSort(arr);
System.out.println("Array after - "+Arrays.toString(arr));
}
public static void countSort(Element[] arr){
int n=arr.length;
int max=arr[0].key;
int min=arr[0].key;
for(Element i:arr){
if(i.key>max){
max=i.key;
}
if(i.key<min){
min=i.key;
}
}
int range=max-min+1;
int[] count=new int[range];
Element[] sortedArray=new Element[n];
for(Element i:arr){
count[i.key-min]++;
}
for(int i=range-2;i>=0;i--){
count[i]=count[i]+count[i+1];
}
for(int i=0;i<n;i++){
sortedArray[n-count[arr[i].key-min]]=arr[i];
count[arr[i].key-min]--;
}
for(int i=0;i<n;i++){
arr[i]=sortedArray[i];
}
}
}
class Element{
private String name;
public int key;
public Element(String name, int key){
this.name=name;
this.key=key;
}
public String toString(){
return "{"+name+":"+key+"}";
}
}
Will this preserve the stability and provide sorting? Or is there something I am missing?

I am trying to print the method findAverage in the main method, can anyone tell me how to fix

public class Grade {
private int [] array = {2,3,1,4,5,7,1};
public int findSum() {
int sum;
sum = 0;
for(int i =0; i <array.length; i++)
{
sum = sum +array[i];
}
return sum;
}
public double findAverage() {
double average;
average = findSum()/array.length;
return average;
}
}
class ExamClient {
public static void main(String[] args) {
double answer;
answer = findAverage();
System.out.println("Average of all elements in the array is" + answer);
}
}
In the main you have to create a instance of the class
Create instance
public static void main(String[] args)
{
double answer;
Grade g= new Grade();
answer = g.findAverage();
System.out.println("Average of all elements in the array is" + answer);
}
Also you can make the method static

Cannot insert multiple elements in PriorityQueue

I'm trying to implement a heap sorting algorithm.
My problem is when I try to insert Elements to my PriorityQueue, it only works for one element. When I add multiple elements to it, I get these errors
Exception in thread "main" java.lang.ClassCastException: Element cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:652)
at java.util.PriorityQueue.siftUp(PriorityQueue.java:647)
at java.util.PriorityQueue.offer(PriorityQueue.java:344)
at java.util.PriorityQueue.add(PriorityQueue.java:321)
at PQHeap.insert(PQHeap.java:47)
at PQHeap.main(PQHeap.java:17)
This is my Element class
public class Element {
public int key;
public Object data;
public Element(int i, Object o) {
this.key = i;
this.data = o;
}}
The interface:
public interface PQ {
public Element extractMin();
public void insert(Element e);
}
And this is the class, which generates the heap. Note that the main class is located here just to debug with. When I only insert Element e, it works. But when I insert f aswell, it give's me the errors above.
import java.util.*;
public class PQHeap implements PQ{
public static void main(String[] args) {
PQHeap hq = new PQHeap(5);
Element e = new Element(5, null);
hq.insert(e);
hq.insert(f);
for(int in = 0; in<hq.pq.size();in++){
System.out.println(hq.pq.remove());
}
}// end of main method
public PriorityQueue<Element> pq;
public PQHeap(int maxElms) {
this.pq = new PriorityQueue<Element>(maxElms);
}
#Override
public Element extractMin() {
Element min = pq.remove();
System.out.println(min.key);
return min;
}
#Override
public void insert(Element e) {
this.pq.add(e);
}

Spliterator Java 8

I have a number from 1 to 10,000 stored in an array of long. When adding them sequentially it will give a result of 50,005,000.
I have writing an Spliterator where if a size of array is longer than 1000, it will be splitted to another array.
Here is my code. But when I run it, the result from addition is far greater than 50,005,000. Can someone tell me what is wrong with my code?
Thank you so much.
import java.util.Arrays;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class SumSpliterator implements Spliterator<Long> {
private final long[] numbers;
private int currentPosition = 0;
public SumSpliterator(long[] numbers) {
super();
this.numbers = numbers;
}
#Override
public boolean tryAdvance(Consumer<? super Long> action) {
action.accept(numbers[currentPosition++]);
return currentPosition < numbers.length;
}
#Override
public long estimateSize() {
return numbers.length - currentPosition;
}
#Override
public int characteristics() {
return SUBSIZED;
}
#Override
public Spliterator<Long> trySplit() {
int currentSize = numbers.length - currentPosition;
if( currentSize <= 1_000){
return null;
}else{
currentPosition = currentPosition + 1_000;
return new SumSpliterator(Arrays.copyOfRange(numbers, 1_000, numbers.length));
}
}
public static void main(String[] args) {
long[] twoThousandNumbers = LongStream.rangeClosed(1, 10_000).toArray();
Spliterator<Long> spliterator = new SumSpliterator(twoThousandNumbers);
Stream<Long> stream = StreamSupport.stream(spliterator, false);
System.out.println( sumValues(stream) );
}
private static long sumValues(Stream<Long> stream){
Optional<Long> optional = stream.reduce( ( t, u) -> t + u );
return optional.get() != null ? optional.get() : Long.valueOf(0);
}
}
I have the strong feeling that you didn’t get the purpose of splitting right. It’s not meant to copy the underlying data but just provide access to a range of it. Keep in mind that spliterators provide read-only access. So you should pass the original array to the new spliterator and configure it with an appropriate position and length instead of copying the array.
But besides the inefficiency of copying, the logic is obviously wrong: You pass Arrays.copyOfRange(numbers, 1_000, numbers.length) to the new spliterator, so the new spliterator contains the elements from position 1000 to the end of the array and you advance the current spliterator’s position by 1000, so the old spliterator covers the elements from currentPosition + 1_000 to the end of the array. So both spliterators will cover elements at the end of the array while at the same time, depending on the previous value of currentPosition, elements at the beginning might not be covered at all. So when you want to advance the currentPosition by 1_000 the skipped range is expressed by Arrays.copyOfRange(numbers, currentPosition, 1_000) instead, referring to the currentPosition before advancing.
It’s should also be noted, that a spliterator should attempt to split balanced, that is, in the middle if the size is known. So splitting off thousand elements is not the right strategy for an array.
Further, your tryAdvance method is wrong. It should not test after calling the consumer but before, returning false if there are no more elements, which also implies that the consumer has not been called.
Putting it all together, the implementation may look like
public class MyArraySpliterator implements Spliterator<Long> {
private final long[] numbers;
private int currentPosition, endPosition;
public MyArraySpliterator(long[] numbers) {
this(numbers, 0, numbers.length);
}
public MyArraySpliterator(long[] numbers, int start, int end) {
this.numbers = numbers;
currentPosition=start;
endPosition=end;
}
#Override
public boolean tryAdvance(Consumer<? super Long> action) {
if(currentPosition < endPosition) {
action.accept(numbers[currentPosition++]);
return true;
}
return false;
}
#Override
public long estimateSize() {
return endPosition - currentPosition;
}
#Override
public int characteristics() {
return ORDERED|NONNULL|SIZED|SUBSIZED;
}
#Override
public Spliterator<Long> trySplit() {
if(estimateSize()<=1000) return null;
int middle = (endPosition + currentPosition)>>>1;
MyArraySpliterator prefix
= new MyArraySpliterator(numbers, currentPosition, middle);
currentPosition=middle;
return prefix;
}
}
But of course, it’s recommended to provide a specialized forEachRemaining implementation, where possible:
#Override
public void forEachRemaining(Consumer<? super Long> action) {
int pos=currentPosition, end=endPosition;
currentPosition=end;
for(;pos<end; pos++) action.accept(numbers[pos]);
}
As a final note, for the task of summing longs from an array, a Spliterator.OfLong and a LongStream is preferred and that work has already been done, see Arrays.spliterator() and LongStream.sum(), making the whole task as simple as Arrays.stream(numbers).sum().

Resources