new to Java. Trying to understand the point of declaring my ArrayList as an <Integer>. I still have to cast my .get() result as an int in my methods for it to work, else it still returns an Object. eg: (int) deliv.get(j) int the Sort method's for loop. Is there a way to avoid this or is my code the correct approach?
Problem: Assume the array can change size, hence not just using primitive array. All numbers should be pairs, looking for the unique one missing it's pair value. I sort the array, then cycle through the pairs to look for a mismatch. Thanks.
import java.util.*;
class StolenDrone{
public static void main(String[] args){
ArrayList<Integer> deliv_id = new ArrayList<>();
deliv_id.add(99);
deliv_id.add(13);
deliv_id.add(4);
deliv_id.add(5);
deliv_id.add(8);
deliv_id.add(99);
deliv_id.add(8);
deliv_id.add(5);
deliv_id.add(4);
System.out.println("Array is: " + deliv_id);
sort(deliv_id);
System.out.println("Array is: " + deliv_id);
int unique = findUnique(deliv_id);
System.out.println("Unique ID is: " + unique);
}
//Sort ArrayList into increasing order
static void sort(ArrayList deliv){
int temp;
for(int i = 0; i<deliv.size();i++){
for (int j=0; j<deliv.size()-1;j++){
if((int) deliv.get(j)> (int) deliv.get(j+1)){
temp = (int) deliv.get(j+1);
deliv.set(j+1, deliv.get(j));
deliv.set(j, temp);
}
}
}
}
//check pairs in ArrayList to find unique entry
static int findUnique(ArrayList deliv){
for(int i = 0; i<deliv.size()-1;i+=2){
if(deliv.get(i) == null){
return -1; //no unique
}
if((int) deliv.get(i) != (int) deliv.get(i+1)){
return (int) deliv.get(i);
}
}
return -1;
}
}
When you type parameterize ArrayList<Integer> the compiler knows that everything inside the ArrayList is of type Integer and will only allow you to add Integers to the list, and thus get() returns Integer. Without parameterizing the compiler will allow you to add any Object to the ArrayList, and thus calling get() will return an Object and requiring the cast to int.
To remove the need for casts you need to change parameters with type ArrayList to ArrayList<Integer> in the function declaration.
static void sort(ArrayList deliv)
Your method signature requests an untyped ArrayList.
The compiler cannot know what will be inside the ArrayList so it requires you to cast the result.
Change it to this:
static void sort(ArrayList<Integer> deliv)
Now the compiler knows it is an ArrayList of Integers.
So you wont need to add the cast to get()
In Java Integet is wrapper-class of int. You cannot set int as a type of ArrayList to work, but you can put there int type and it will be automatticly casted to Integer. To meke work it good you should do like this :
static void sort(ArrayList deliv){
int temp;
for(int i = 0; i<deliv.size();i++){
for (int j=0; j<deliv.size()-1;j++){
if(deliv.get(j)> deliv.get(j+1)){ // You should not cast, Integer is Comparable
temp = deliv.get(j+1).intValue();//Changes here
deliv.set(j+1, deliv.get(j).intValue());//And here
deliv.set(j, temp);
}
}
}
}
Good luck
Related
I'm having trouble understanding how to return an array of user defined size in a method which return type is Integer[]. The class which contains this method extends an interface, if that makes any difference here (I don't think it does, but correct me if I'm wrong).
When trying to return a, java tells me the type is incompatible. I'm not sure if the problem lies in my method body, or if there's a particular way to phrase the return statement since the return type is Integer[]. I need to return the array without assigning a value to size, as size will be assigned a value in the main method. Please advise and explain what I'm doing wrong here. Thanks in advance!
#Override
public Integer[] generateTestDataBinary(int size) {
Comparable[] a = new Comparable[size];
for (int i = 0; i < size; i++) {
if (size <= size/2) {
a[i] = 0;
}
else {
a[i] = 1;
}
}
return a;
}
This array will be used to test the time complexity of different sorting algorithms. I have to create two more arrays after this one, each one slightly different than the last, so I need to know how to implement this method in order to finish the program. Please let me know if more code is needed to understand the context of the problem.
An Integer[] is Comparable[], but a Comparable[] is not an Integer[].
Change your type from Comparable[] to Integer[].
See java.lang.Comparable's API doc:
All Known Implementing Classes:
..., Integer, ...
and java.lang.Integer's API doc:
All Implemented Interfaces:
..., Comparable
That means an Integer is a Comparable but a Comparable is not an Integer. You cannot assign a value of a super-type (Comparable) to a variable of a sub-type (Integer). Likewise, you cannot return a value of a super-type (Comparable) from a method of a sub-type (Integer) be it an array or not:
Type mismatch: cannot convert from Comparable[] to Integer[]
The reason is: A super-type doesn't know anything about the extensions of its sub-type(s) (remember the class declaration syntax class <sub-type> extends <super-type>). Hence, assigning an object with less information (the super-type) to an object variable that is supposed to hold and has according space for more information (the sub-type) would lead to undefined areas.
So, the following compile:
public Integer[] generateTestDataBinary(int size) {
Integer[] a = new Integer[size];
// ...
return a;
}
public Comparable<Integer>[] generateTestDataBinary(int size) {
Integer[] a = new Integer[size];
// ...
return a;
}
public Comparable<Integer>[] generateTestDataBinary(int size) {
Comparable<Integer>[] a = new Comparable[size];
// ...
return a;
}
I got this code:
public static ArrayList<Integer> MakeSequence(int N){
ArrayList<Integer> x = new ArrayList<Integer>();
if (N<1) {
return x; // need a null display value?
}
else {
for (int j=N;j>=1;j--) {
for (int i=1;i<=j;i++) {
x.add(Integer.valueOf(j));
}
}
return x;
}
}
I am trying to call it from the main method just like this:
System.out.println(MakeSequence (int N));
but I get an error...
Any recommendations? Much appreciated, thanks!
System.out.println(MakeSequence (int N));
should be
int N = 5; // or whatever value you wish
System.out.println(MakeSequence (N));
Just pass a variable of the correct type. You don't say that it is an int again;
You define the method as follow MakeSequence (int N), this means that method expects one parameter, of type int, and it'll be called N when use inside the method.
So when you call the method, you need to pass an int like :
MakeSequence(5);
// or
int value = 5;
MakeSequence(value);
Then put all of this in a print or use the result in a variable
System.out.println(MakeSequence(5));
//or
List<Integer> res = MakeSequence(5);
System.out.println(res);
All of this code, to call the method, should be in antoher method, like the main one
Change x.add(Integer.valueOf(j)); to x.add(j); as j is already an int
to follow Java naming conventions : packages, attributes, variables, parameters, method have to start in lowerCase, while class, interface should start in UpperCase
The first issue is I think that N should be some int value not defining the variable in the method call. Like
int N = 20;
ClassName.MakeSequence(N);
The other issue you will face. As System.out.println() only prints string values and you are passing the ArrayList object to it, so use it like this System.out.println(ClassName.MakeSequence(N).toString())
So I've been given the following problem:
Write a program that creates a List of Rationals and sorts them into increasing
order. Use appropriate methods from the Collections Framework classes to sort
the elements into increasing order.
I've created a 'Rational' class to represent rational numbers and I've also made the list of random Rational numbers. But I'm having trouble figuring out a way to implement a method of sorting the list. Here's samples of the code before I go on further:
public class Rational implements Comparable<Rational> {
private int num;
private int denom;
private int common;
// Default constructor initialises fields
public Rational() throws IllegalNumDenomException {
setNum(1);
setDenom(2);
}
// Constructor sets fields with given parameters
public Rational(int num, int denom) throws IllegalNumDenomException {
common = gcd(num,denom);
setNum(num/common);
setDenom(denom/common);
}
//Compares two rational numbers
public int compareTo(Rational rhs) {
int tempNumerator = this.getNum() * rhs.getDenom();
int tempNumeratorRhs = rhs.getNum() * this.getDenom();
//Compares rationalised numerators and returns a corresponding value
if (tempNumerator < tempNumeratorRhs) {
return -1;
} else if (tempNumerator > tempNumeratorRhs) {
return 1;
}
return 0;
}
// Overriden toString method
public String toString() {
return num + "/" + denom;
}
//Calculates the GCD of a fraction to simplify it later on
public int gcd(int x, int y) throws IllegalNumDenomException{
while(x != 1){ //Prevents infinite loop as everything is divisible by 1
if(x == y){
return x;
}
else if(x>y){
return gcd(x-y,y);
}
return gcd(x,y/x);
}
return 1;
}
public class RationalList {
public static void main(String[] args) throws IllegalNumDenomException {
List<Rational> rationals = new ArrayList<Rational>();
Random rand = new Random();
int n = rand.nextInt(50) + 1;
//Generates 9 random Rationals
for(int i = 1; i<10; i++){
rationals.add(new Rational(i,n));
n = rand.nextInt(50) + 1;
}
System.out.println("Original Order: " + rationals.toString());
sort(rationals);
System.out.println(rationals);
}
public static List<Rational> sort(List<Rational> rationals){
//Use compareTo method inside a loop until list is sorted
return rationals;
}
Sorry it's a bit long. So my thinking is creating a sort method and using the compareTo method to determine if a Rational is in the correct place, if not swap it. But then I'm unsure if you're able to even move elements around in a list like you can in an array. So I then thought maybe I need to implement the Collections.sort() method and override the sort method but I get to the same problem. Maybe I could use .toArray?
Can anyone shed some light on the way to do this please? Just hints would be useful.
Since you implemented comparable, Collections.sort(rationals) will work.
This is because Collections.sort will work on any List of Comparable things. It has already been designed to use the Comparable.compareTo() method that you have defined, and as long as your compareTo is implemented correctly it should sort your list.
What you are doing is roughly correct.
But then I'm unsure if you're able to even move elements around in a list like you can in an array.
Under the hood, the Collections.sort method can copy the elements of the list into an array, sort the array, and then rebuild the list from the sorted array. The actual behavior depends on the list implementation class.
In the main method of your application you should create a list of Rationals and then use the Collections.sort() method.
You should generate the random list of Rationals and then use Collection.sort(rationalsList);
First of all, sorry for asking such a vague question, I did not know how else to put it.
If I have a class Heap:
public class Heap<T> {
private T[] arr;
private int heapSize;
public T peek() {
if (heapSize > 0) {
return arr[0];
} else {
return null;
}
}
}
and another method somewhere:
double mean(int a, int b) {
return (a + b)/ 2.0;
}
which is called as
mean(heapA.peek(), heapB.peek());
It throws an error saying mean(int, int) cannot be applied to (Object, Object).
Something like this would have worked for an ArrayList or some other inbuilt structure.
What am I missing here?
Typecasting fixes this but I am just curious as to why this works for say ArrayList but not for my class.
The way you create ArrayList, you need to create object of Heap.
ArrayList<Integer> list = new ArrayList<Integer>();
Did you notice <Integer> in the declaration?
Heap<Integer> heapA = new Heap<Integer>();
Now no need to add casting mean method.
I am currently working on a project and I have an array of Objects. I know that the array will store the following types: Product, Food, Clothes (food and clothes are both subclasses of Product). The thing is that I am trying to access an attribute of an object from the array (barCode), but when I try to do that it gives me an error and says that "barCode is undefined for type Object".
How can I solve this problem?
I cannot create an separates array for every type because it won't be scalable when I would add more classes and types.
Thanks!
yes. the future classes will also be sublcasses of Product
this is one instance of the code. the only problem is on the lines with getBarCode() (which is a method for the Product class)
private Object arr[] = super.getArray();
public void sort(int c)
{
Object aux;
int min = 999, poz;
for(int i = 0; i < super.getIndex() - 1; i ++)
{
for(int j = i; j < super.getIndex(); j ++)
{
if( arr[j].getBarCode() < min)
{
min = arr[j].getBarCode();
poz = j;
}
}
aux = arr[i];
arr[i] = arr[poz];
arr[poz] = aux;
}
}
If you could guarantee that the method barCode exists on Product and its children, then you could just use an array of Product instead.
You would have to deal with any sort of fiddly casting you would want to do if you want to use specific child class methods, but that would at least let you call the same method on all elements without too much worrying.
So long as getArray can be changed to return Product, then you can write this:
private Product[] arr = super.getArray();
You'd change aux to a type of Product, too.
When accessing the object from the array, what you can do is compare the object type.
Like this:
Object o = array[0];
if(o.getClass().equals(Product.class)) {
Product p = (Product)o;
p.getBarcode();
}
Alternatively, if all of your objects you are putting into this array are subclasses of Product, just make an arrayList to use Products, like new ArrayList(), and then call the barcode method for there.