so I'm trying to write a method which uses generics. The method is suppose to takes a arrayList and return the highest value in the array. Here is the code to do that
public T largest() {
T value = myList.get(0);
for (int i = 1; i < myList.size(); i++) {
if (myList.get(i).doubleValue() > value.doubleValue()) {
value = myList.get(i);
}
}
return value;
}
Only problem is I'm not suppose to use .doubleValue. I've been stuck trying to figure it out for hours with no luck, Generics are reallyyyyy throwing me off for some reason. Am I suppose to somehow cast something? How can I write that above method without using .doubleValue()? Thanks!
I think this is what they had in mind when giving you this task.
The elements of your list need to be something that is Comparable.
This way you can compare them simply by calling compareTo.
This implementation is more general, more generic.
That is you don't need to limit yourself to using doubleValue in particular.
package test;
import java.util.Arrays;
import java.util.List;
public class Test001 {
public static void main(String[] args) {
Long a = largest(Arrays.asList(new Long[]{2L, 5L, 7L}));
Integer b = largest(Arrays.asList(new Integer[]{2, 5, 7}));
System.out.println(a);
System.out.println(b);
}
public static <T extends Comparable<? super T>> T largest(List<T> myList) {
T value = myList.get(0);
for (int i = 1; i < myList.size(); i++) {
if (myList.get(i).compareTo(value) > 0) {
value = myList.get(i);
}
}
return value;
}
}
You can only find the largest element if an ordering of the elements is defined. Since you're got giving a Comparator to the method to specify such an order, you're assuming "natural order", which means the elements must be Comparable.
Your function changes to the following (changed to static to make this standalone answer "complete"):
public static <T extends Comparable<T>> T largest(Iterable<T> myList) {
T largest = null;
for (T value : myList)
if (largest == null || value.compareTo(largest) > 0)
largest = value;
return largest;
}
Related
I am trying to return the sorted version of arrnew but it keeps giving me an error on the part Collections.sort(arrnew). My goal of this code is to accept a variable n .I find all factorial numbers of n and find prime factors of those numbers and add it to the array.
import java.util.List;
import java.util.*;
import java.io.*;
public class test2 {
public static List<Integer> factorFactorial(int n) {
ArrayList<Integer> arrnew = new ArrayList<>();
while(n>0) {
int x=n;
for (int i = 2; i <= x ; i++) {
while (x % i == 0) {
arrnew.add(i);
x = x / i;
}
}
n--;
}
;
return Collections.sort(arrnew);
}
public static void main(String[] args) {
List<Integer>a=factorFactorial(10);
for(int x:a){
System.out.print(x);
}
}
}
Collections.sort() returns void, but you have specified your method should return a list. You can simply change your code to return the sorted list:
Collections.sort(arrnew)
return arrnew;
The Collections.sort signature is public static <T extends Comparable<? super T>> void sort​(List<T> list), so as it is void it doesn't return the given list, you have to split it in
Collections.sort(arrnew)
return arrnew;
Or using Stream you can inline it and return a new list object
return arrnew.stream().sorted().collect(Collectors.toList());
Here's my java code and the problem is that the use of relational
operator(<) inside binarySearch() is giving error.
I guess this error I am getting because the operands are of type object.
How to remove this error so my function runs perfectly?
import java.util.Random;
import java.util.Arrays;
class BinarySearch
{
public static void main(String $[])
{
Integer arr[]=new Integer[20];
for(int i=0;i<20;i++)
arr[i]=(new Random()).nextInt()%10000;
display("Initial array :\n");
array(arr);
Arrays.sort(arr);
display("After sorting :\n");
array(arr);
display("Enter the element to be searched for : ");
Integer elem=(new java.util.Scanner(System.in)).nextInt();
display(elem+(binarySearch(arr,elem)?" Found":" Not found")+"\n");
}
public static <T>boolean binarySearch(T arr[],T val)
{
int start=0;
int end=arr.length-1;
while(start<=end)
{
int mid=(start+end)/2;
if(arr[mid]==val)
return true;
if(arr[mid]<val)
start=mid+1;
else
end=mid-1;
}
return false;
}
public static void display(Object o)
{
System.out.print(o);
}
public static <T>void array(T arr[])
{
for(int i=0;i<arr.length;i++)
display(arr[i]+" ");
display("\n");
}
}
The problem is that your binarySearch() method is accepting parameters that will be Objects rather than primitive types, so it is unwise to compare them using the equality operator == and invalid to compare them using the less than operator <. Instead define your binarySearch method as follows:
public static <T extends Comparable<T>> boolean binarySearch(T arr[],T val) {
int start = 0;
int end = arr.length-1;
while(start <= end) {
int mid=(start+end)/2;
int comparison = arr[mid].compareTo(val);
if(comparison == 0) {
return true;
}
if(comparison < 0) {
start = mid+1;
}
else {
end = mid-1;
}
}
return false;
}
Read here about generics. Since all generics are objects - you can't use comparison operators with them. Even if you type <T extends Number.
There are two ways to handle this:
Pass Comparator<T> to the method and use comparator.compare(arr[mid], val) for comparing values.
Write <T extends Comparable> and call arr[mid].compareTo(val).
Both these methods return an integer value:
0, if values are equal
negative, if first value less than second
positive, if first value greater than second
I am trying to resolve an excercise about finding out the lowest value in array using loop. The excercise is about generics. But i have a hard to find out the solution. For an array of string i will use " if (minimum.compareTo(list[i]) > 0) ". I am stuck in how to do this with an array of integer. Any hint or help is very appreciate.
There is my code:
public class Excercise {
public static void main(String[] args) {
//Create an array
Integer[] intArray = { new Integer(45), new Integer(2), new Integer(6), new Integer(15) };
//print the lowest value
System.out.print(min(intArray));
// min(intArray);
}
public static <E extends Comparable<E>> E min(E[] list) {
E minValue = list[0];
for(int i = 1; i < list.length; i++) {
if(minValue.compareTo(list[i]) { <-- i get an error her
minValue = list[i];
return minValue;
}
}
compareTo doesn't return a boolean, so you can't use it as a condition of your if clause.
See http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html#compareTo%28T%29
Instead, it an returns int. If the result is above zero, that means the first term is greater. If it is below, it is lesser.
So use if(minValue.compareTo(list[i])>0)) instead.
There are other bugs in the code (mostly typos). I will leave those to you.
because compareTo() method will return integer value
change
if(minValue.compareTo(list[i]) {
to
if(minValue.compareTo(list[i]) > 0) {
The proper method should be as follows:
public static <E extends Comparable<E>> E min(E[] list) {
E minValue = list[0];
for(int i = 1; i < list.length; i++) {
if( minValue.compareTo(list[i]) > 0) { //compareTo always returns an int
minValue = list[i];
}
}
return minValue; // returs the minimum after checking all the array
}
For my assignment, I have to create both a method to sort integers and Strings stored in an object class. Keep in mind, I HAD TO USE CASTS. I wanted to use generics, but my teacher INSISTS on me using 1.4.2 (which don't have generics). I can sort time, and for the alphabetical sort, I used my method to sort time and added a compareTo. I played with it a bit, but when I output it, it gives me everything I inputted in the order I inputted it. Not in alphabetical.
Here's the class I created to store input:
public class showInfo
{
String name;
String day;
int time;
}
The following is the method to sort by name!
//method to sort and display info
public static void sortName(){
for(int i = 0; i < show.size() - 1; i++) {
for(int j = 0; j < show.size() - 1; j++){
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
showInfo temp = new showInfo();
temp.name = ((showInfo)show.get(j)).name;
temp.day = ((showInfo)show.get(j)).day;
temp.time = ((showInfo)show.get(j)).time;
((showInfo)show.get(j)).time = ((showInfo)show.get(i)).time;
((showInfo)show.get(j)).day = ((showInfo)show.get(i)).day;
((showInfo)show.get(j)).name = ((showInfo)show.get(i)).name;
((showInfo)show.get(i)).time = temp.time;
((showInfo)show.get(i)).day = temp.day;
((showInfo)show.get(i)).name = temp.name;
}
}
}
Any help would be great! Thanks in advance. :)
(PS. I'm aware I need to change "showInfo" to "ShowInfo", but I'll do it when I'm finished.)
One problem with your code is that you are comparing show.get(i) with show.get(i+1) but then swapping show.get(i) with show.get(j). You should be comparing to show.get(j). Also, the inner loop should go to j < show.size() rather than show.size() - 1. Finally, you can start the inner loop at i + 1 instead of at 0.
Once you determine that you need to swap, you can do much better by simply swapping references in the list, rather than swapping each field:
showInfo tmp = (showInfo)show.get(i);
show.set(i, show.get(j));
show.set(j, tmp);
I assume show is a List and you have to sort by name.
First, make showInfo implement Comparable:
public class showInfo implements Comparable
{
String name;
String day;
int time;
public int compareTo(Object o)
{
showInfo other = (showInfo) o;
return name.compareTo(other.name);
}
}
Then, use `Collections.sort()' on the list:
Collections.sort(show);
You can do something like this....
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class myComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((o1.toString().charAt(0) > o2.toString().charAt(0)) ? 1 : (o1
.toString().charAt(0) == o2.toString().charAt(0)) ? 0 : -1);
}
}
public class Sample {
/**
* #param args
*/
public static void main(String[] args) {
List l = new ArrayList();
l.add("hello");
l.add("abc");
l.add("World");
l.add("hi");
System.out.println("Before sorting");
for (Object i : l) {
System.out.println(i.toString());
}
Collections.sort(l, new myComparator());
System.out.println("After sorting");
for (Object i : l) {
System.out.println(i.toString());
}
}
}
You are incorrectly using i here :
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(i+1)).name) > 0){
I believe the second i should be j to achieve bubble sort
if(((showInfo)show.get(i)).name.compareTo(((showInfo)show.get(j+1)).name) > 0){
Not sure if this is what you look for, it uses casting insteads of generics, anyway, i hope this will help
pastebin
This question is kind of long... so bear with me please.
I have to convert a SelectionSort method that was covered in my book that was built to sort arrays, and make it generic so that I can enter either doubles or ints into it and have it work.
It doesn't seem to allow generic arrays, so I'm attempting to use an ArrayList. The problem here is since the int and doubles are now in Integer and Double wrappers, it breaks the SelectionSort method.
I've attempted to fix it, but I'm having no luck. I'll post the original SelectionSort method below, and then the class and driver that I'm creating.
Original SelectionSort:
public class SelectionSort {
private int[] data;
private static final Random generator = new Random();
public SelectionSort(int size) {
data = new int[size];
for(int i = 0; i < size; i++) {
data[i] = 10 + generator.nextInt(90);
}
}
public void sort() {
int smallest;
for(int i = 0; i < data.length - 1; i++) {
smallest = i;
for(int index = i + 1; index < data.length; index++) {
if(data[index] < data[smallest]) {
smallest = index;
}
}
swap(i, smallest);
}
}
public void swap(int first, int second) {
int temporary = data[first];
data[first] = data[second];
data[second] = temporary;
}
}
My simple driver program:
public class GenericsDriver {
public static void main(String[] args) {
SelectionSort<Integer> intSort = new SelectionSort<Integer>();
intSort.AddGrade(100);
intSort.AddGrade(90);
intSort.AddGrade(50);
intSort.AddGrade(80);
intSort.AddGrade(95);
intSort.PrintNumbers();
//sort here
intSort.PrintNumbers();
SelectionSort<Double> doubleSort = new SelectionSort<Double>();
doubleSort.AddGrade(100.1);
doubleSort.AddGrade(90.4);
doubleSort.AddGrade(50.7);
doubleSort.AddGrade(100.2);
doubleSort.AddGrade(100.5);
doubleSort.PrintNumbers();
//sort here
doubleSort.PrintNumbers();
}
}
The new class and my attempt to repurpose the SelectionSort method:
import java.util.*;
public class SelectionSort <T> {
private Array<T> numbers;
public SelectionSort() {
numbers = new ArrayList<T>();
}
public void AddGrade(T number) {
numbers.add(number);
}
public void PrintNumbers() {
System.out.println(numbers.toString());
}
public <T extends Comparable<T>> selectionSort() {
int smallest;
for(int i = 0; i < numbers.size(); i++) {
smallest = i;
for(int index = i + 1; index < numbers.size(); index++) {
if(numbers.) {
//I've tried everything here...
//from using number.get(index), and everything else
//I could think of
}
}
}
}
public void swap(int first, int second) {
}
}
As you can see... I haven't had any luck with sort or swap within my new class. I can't get it to work. My instructions have a hint that I should use > in my sort method...but nothing is giving me the ability to use a .compareTo() method.
This is the actual directive from my book:
Write a generic method selectionSort based on the sort program of Fig 19.6 and 19.7 (That's the code I gave above). Write a test program that inputs, sorts and outputs an Integer array and a Float array. Hint: Use > in the type-parameter section for method selectionSort, so that you can use method compareTo() to compare the objects of the type that T represents.
Could someone please give me some guidance here? Thanks.
It seems that you are new to generics. If you want the program to be the way you wrote it, I can point out few mistakes, which you can improve and then try running your program.
In the third code listing where you defined the class as
SelectionSort <T>
The declaration
private Array<T> numbers;
is incorrect because you do not want this Array class, you can instead use the following:
private List<T> numbers;
Also, there is no point declaring the new selectionSort() generic method as
public <T extends Comparable<T>> selectionSort() {
Do you seriously want a Comparable or its sub class to be the return type?
No, you want a List of T to be returned as an output of the selection Sort process.
Please get back if you still have any doubts.
Happy to Help
Dharam
A quick peek at the javadocs (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html ) shows that Double implements the Comparable interface, which means that it will have a compareTo() method.
The point that your book is trying to force you to get your head around is the concept that you can have multiple types (Integer, Double) that implement the same interface (Comparable), and that you can take advantage of that in your code.
So:
Double firstDouble = Double.valueof(42.0);
Double secondDouble = Double.valueof(43.0);
Integer firstInteger = Integer.valueof(42);
Integer secondInteger = Integer.valueof(43);
so you could write: firstDouble.compareTo(secondDouble) and firstInteger.compareTo(secondInteger) - but by implementing your sort on Comparable (instead of Integer, Double, etc...), you can just use:
numbers.get(i).compareTo(numbers.get(i+1));
hth
Use a comparator. This SO answer has some details. You can use the same concept to define your own comparators. That way your sorting algorithm is truly generic and can handle any data type (complex numbers for example)