What does "T" represent in this code? - java

T get(int i) {
if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException();
return a[i];
}
T set(int i, T x) {
if (i < 0 || i > n - 1) throw new IndexOutOfBoundsException();
T y = a[i];
a[i] = x;
return y;
}
I'm looking over some coding examples from my textbook, but they never mention what T is. I'm not sure how to search about this since I don't know what it's called or it's purpose.
I was wondering if someone can show me a write-up or some info about this. Thank you

T represents an object type using generics.
Whatever type x is in the set call, the set method will return that same type. In the get call, the return type is T, too. That type must be defined somewhere else, probably in the type of the class, where it might show up as <T>.
So if this is a class that is some sort of collections (since it is dealing with indexes), it might be defined as:
public class SomeCollection<T> {
Then it might get instantiated like:
SomeCollection<String> arr = new SomeCollection<String>();
In that case, T would be String, and the return type of the get and set methods, and the type of set parameter x, would all be String.
If it gets instantiated like:
SomeCollection<Integer> arr = new SomeCollection<Integer>();
then T is an Integer.
You could have both in the same code, without having to write two (or more) different versions of SomeCollection.

Related

Converting from Integer wrapper class to int primitive class

I've been trying to convert an Integer Wrapper class to int primitive class. I haven't yet found a proper way to make the code compile. I'm using Intellij IDEA, Java 11 Amazon Coretto, but I need to run it on a computer that runs java 8.
Here's the original code below:
static class Line<Integer> extends ArrayList<Integer> implements Comparable<Line<Integer>> {
#Override
public int compareTo(Line<Integer> other) {
int len = Math.min(this.size(), other.size());
for (int i = 0; i < len; i++) {;
if ((int) this.get(i) != (int) other.get(i)) {
if ((int this.get(i) < (int) this.get(i)) {
return -1;
} else if ((int) this.get(i) > (int)this.get(i)) {
return 1;
} else {}
}
}
...
note that the Line is inserted to an ArrayList.
Originally I used forced casting on all the Integer objects so it'll be like (int) this.get(i). It worked on my local terminal and my Intellij wasn't bothered about it, but unfortunately not the other computer. It couldn't compile there
I thought it was because of the forced casting, since the other computer returned
Main.java:159: error: incompatible types: Integer cannot be converted to int
if ((int) this.get(i) != (int) other.get(i)) {
^
where Integer is a type-variable:
Integer extends Object declared in class Line
so I deleted them all and thought I could let the machine unbox the Integer wrapper on its own. It still didn't compile.
If the code is left like what's written above (no forced casting), it will return "Operator '<' not applicable for 'Integer', 'Integer'"
So I used the .compareTo() method. Compile error.
Then I tried to assign them to an int variable. Intellij IDEA was screaming at me that it required int but found Integer instead. So I force-casted, like so
int thisLine = (int) this.get(i);
int otherLine = (int) other.get(i);
if (thisLine != otherLine) {
if (thisLine < otherLine) {
return -1;
} else if (thisLine > otherLine) {
return 1;
} else {}
Nope, didn't work. Removing the cast also didn't work.
I looked up the Javadocs (https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#intValue--) this time about the Integer class and found a promising little method called intValue(). Problem is? Intellij cannot resolve that method (oddly, VSCode does not consider this an error). I used it like this
int thisLine = this.get(i).intValue();
int otherLine = other.get(i).intValue();
if (this.get(i) != other.get(i)) {
if (thisLine < otherLine) {
return -1;
} else if (thisLine > otherLine) {
return 1;
and sure enough, another compile error on that stubborn computer.
I'm running out of options. I'm seriously considering creating a new custom class just so I can store int values in an ArrayList without having to deal with all this Java backwards incompatibility nonsense.
Anyone here know a consistent method for converting an Integer wrapper object to an int primitive object in Java?
This is the clue in the error message that explains it:
where Integer is a type-variable:
Integer extends Object declared in class Line
Integer is not java.lang.Integer but a type variable with a confusing name...
You declared the type variable here:
static class Line<Integer> extends ArrayList<Integer> implements Comparable<Line<Integer>>
It's as if you declared it like this:
static class Line<T> extends ArrayList<T> implements Comparable<Line<T>>
but by naming the type variable Integer instead of T, and then you try to cast objects of the type T to int later on.
Fix it by not declaring a type parameter named Integer, you don't need that here:
static class Line extends ArrayList<Integer> implements Comparable<Line<Integer>>
You shouldn't have to cast an Integer to an int at all. Integer class has .compareTo methods which compare two integers.
A 0 means value1 is equal to value2. -1 is value1 is less than value2 and a 1 is value1 is greater than value2.
Try the following:
public int compareTo(Line<Integer> other) {
//get the smallest length
int len = this.size() <= other.size() ? this.size() : other.size();
for (int i = 0; i < len; i++) {
int compare = this.get(i).compareTo(other.get(i));
if (compare != 0) { //if compare is not zero they are not the same value
return compare;
}
}
//If we get here, everything in both lists are the same up to "len"
return 0;
}
The compareTo() method is a method of Integer class under java. lang
package. ... It returns the result of the value 0 if Integer is equal
to the argument Integer, a value less than 0 if Integer is less than
the argument Integer and a value greater than 0 if Integer is greater
than the argument Integer.
In you class "Integer" is not a java.lang.Integer but a Generic class that is the reason

What will be the return statement of a method, which creates an array of size n, with return type Integer[]?

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;
}

Java : To write a method that can be applied on any kind of array

Hi and thanks for noticing my problem. I want to write a method that can be used by different types of arrays. But my code always looks like this:
public int indexOf_1(int[] a,int b){
//Find the first matched result and return, otherwise report -1
int index = -1;
for(int j=0;j<a.length;j++){
if (a[j]==b)
{index=j;}
}
return index;
}
public int indexOfChar_1(char[] a,int b){
//Consider merged to the previous method?
int index = -1;
for(int j=0;j<a.length;j++){
if (a[j]==b)
{index=j;}
}
return index;
}
That seems to be redundant and I'm completely uncomfortable with such code duplication. Is there any way to write a searching method for all kinds of array to avoid repeating in this case? Thanks!
Unfortunately because the way arrays and the JVM work, this can't be reduced. Not even generics can help since int[] cannot be safely cast to Object[] without explicit conversion.
This looks like a common util function. If you're not comfortable with the code duplication, you can consider using one of the many libraries which provide this functionality. Guava and Commons-Lang are a few.
Guava puts them in the class relevant to the primitive type. Commons-Lang arranges them in the ArrayUtils class
e.g.
Bytes.indexOf(byteArray, (byte) 2);
Ints.indexOf(intArray, 22);
ArrayUtils.indexOf(intArray, 6);
Well you could use Object[] but you might not want to use ==, since it will compare identity of objects instead of values, instead you probably want to use .equals(). (Unless you know the value will always be a char or int) Perhaps this:
public int indexOf(Object[] a, int b) {
int index = -1;
for (int j = 0; j < a.length; j++) {
if (a[j].equals(b)) {
index = j;
}
}
return index;
}
public static <T> int index_Of(Object[] input,T value){
//Find the first matched result and return, otherwise report -1
for(int j=0;j<input.length;j++){
if(input[j].equals(value))
return j;
}
return -1;
}
You can generalize you method to deal with all kind of arrays. However, please pay more attention to the type. If you want to use Object referring to primitive type, when declaring a primitive type array, you need to use reference type. For example,
Character [] a = new Character[]{'a','b','c'};
DO NOT use char, since it will compile error when type checking.

The operator > is undefined for the argument type(s) java.lang.Object, java.lang.Object

public void sort(){
//TO DO
int k = start;
int temp = 0;
for(int i=0; i<size-1; i++){
for(int j=0; j<size-1; j++){
if((cir[(k % cir.length)]) > cir[((k+1) % cir.length)]){
temp = cir[(k % cir.length)];
cir[k%cir.length] = cir[(k+1)%cir.length];
cir[(k+1)%cir.length] = temp;
}
k = (k+1)%cir.length;
}
}
}
//Here the cir[] type is object. but why this problem is occurring?
The operators <,> are not defined for Object.
How would you compare them?
Define a method for the class of the object you are using. Say greaterThan(YourObjectType otherobject). Then implement it according to how you want to compare. That depends on YourObjectType.
Edit.
Implement the Comparable interface as added in a comment.
The others have already mentioned it but I will reiterate: if you want to write some generic sort method you'd want to either provide a Comparator or have the elements implement Comparable.
With generics your methods could look like this:
public <T extends Comparable<T>> void sort(T[] array) { ... }
public <T> void sort(T[] array, Comparator<T> comparator) { ... }
Both variants require the user to provide some code that defines how <, == and > are defined for the objects in question (the methods Comparable.compareTo(right) or Comparator.compare(left, right) return a negative (normally -1) int, 0 or a positive int (normally 1) to indicate <, == or >).
In general, you'd use Comparable if you can define a natural (default) ordering, e.g. if you'd work with an array of people they normally might be ordered by name.
Comparator on the other hand is more flexible and normally used if you can't or don't want to use a default order. In that case you'd provide a comparator for each case, e.g. when you'd want to sort cars either by price or speed you'd provide a comparator that internally either compares prices or speed.
Note that this doesn't work for primitives like int etc. Thus you'd either have to convert them to their wrapper classes, e.g. Integer or provide custom methods that make use of the "normal" operators.

Generic Binary Search - JAVA -

I dont know if the functionality of my code is the correct one for binary search BUT this is not my question, I want to solve it myself.
My problem is in testing its functionality while I get the following errors:
I really dont know how to solve this issue. Please help me!
My code:
public class BinarySearchGeneric<T extends Comparable<T>>{
public int search(T[] array, T element){
int start = 0;
int end = array.length - 1;
int mid = (start + end) / 2;
while(!element.equals(array[mid]) && end != 0) {
if (element.equals(array[mid])) {
return mid;
} else if (array[mid].compareTo(element) < 0) {
end = mid - 1;
mid = (start + end) / 2;
} else if(array[mid].compareTo(element) > 0){
start = mid + 1;
mid = (start + end) / 2;
}
}
return -1;
}
}
Main Method:
public class Main {
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8,9,10};
BinarySearchGeneric binarySearchGeneric = new BinarySearchGeneric(a);
System.out.println("BinarySearch Generic: " + binarySearchGeneric.search(a, 8));
}
}
There are two compilation issues here:
There is no constructor of BinarySearchGeneric which takes a parameter, but you're trying to pass the parameter. Remove it:
BinarySearchGeneric binarySearchGeneric = new BinarySearchGeneric();
int[] is not an acceptable parameter to a generic method expecting an array, because int is a primitive type, not a reference type, and so can't be used in generics. The solution is simply to declare an array of Integer, rather than int:
Integer[] a = {1,2,3,4,5,6,7,8,9,10};
The compiler converts these int literals to Integer instances automatically.
But there are more issues.
You're declaring a variable of raw type. This basically switches off the compiler's type checking associated with that variable, making it likely that you will make a type error. Add the generic parameters:
BinarySearchGeneric<Integer> binarySearchGeneric = new BinarySearchGeneric<>();
Arrays and generics don't really play well together. Things would start get a bit messy if you declared a generic, comparable class:
class GenericComparable<T> extends Comparable<T> { ... }
and then tried to declare an array of GenericComparables to pass to binarySearchGeneric, since you can't directly create a generic array.
It's much easier simply to avoid arrays, and use a List<T> instead:
public int search(List<T> array, T element){
Potentially, you have inconsistent behaviour, because you are mixing equals and compareTo in the search. Whilst compareTo should be consistent with equals (in the sense that a.compareTo(b) <=> a.equals(b), it isn't necessarily true.
You can make the behaviour consistent by only using compareTo:
int c = array[mid].compareTo(element);
if (c == 0) {
// ...
} else if (c < 0) {
// ...
} else {
// ...
}
I don't see a user defined constructor for the BinarySearchGeneric class, so your code should look something like this:
BinarySearchGeneric binarySearchGeneric = new BinarySearchGeneric();
System.out.println("BinarySearch Genetic: ", binarySearchGeneric(a, 8));

Categories