// Concrete implementation built atop skeletal implementation
static List<Integer> intArrayAsList(final int[] a) {
if (a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
};
}
So far I knew we can not instantiate an abstract class at all . But what aren't we doing the same thing here with return new AbstractList<Integer>() ? I am confused .
No, you are creating an anonymous class. You are subclassing your abstract class and you provide an implementation and instantiate it at the same time.
If you try this:
return new AbstractList<Integer>();
you will get an error since you won't be providing a concrete implementation.
If you are confused you can always check out the official tutorials. Here it is:
Java Inner Classes
You are creating an anonymous class which is inheriting the abstract class.
You need to implement all abstract methods of the Abstract class into the anonymous class.
No, it is not instantiating an abstract class, since the code provides an implementation to that class. It is like an anonymous inner class.
Just as information, all types of inner classes generates a .class file after the compilation process. So, the code:
Test.java
public class Test {
abstract class Foo {
abstract void foo();
}
public Foo bar() {
return new Foo() {
#Override
void foo() {
System.out.println( "foo!!!" );
}
};
}
public static void main( String[] args ) {
new Test().bar().foo();
}
}
Will generate:
Test.class: The public class of the file (Test.java)
Test$Foo.class: The abstract inner class inside the Test class.
Test$1.class: The anonymous inner class coded inside the bar method.
No, you are creating an anonymous class.
Your Code:
return new AbstractList<Integer>() {
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
};
Is Equivilent to:
...
return new myNewClass()
...
public class myNewClass extends AbstractList<Integer>{
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // Auto-unboxing
return oldVal; // Autoboxing
}
public int size() {
return a.length;
}
}
Related
First I got a class named after my Chinese name
public class Yxj<T> {
private T[] data;
private int size = 0;
private final Comparator<? super T> comparator;
public Yxj(Comparator<? super T> c) {
data= (T[]) new Object[16];
comparator = c;
}
public void addItem(T t){
data[size++] = t;
}
public int sort(){
return comparator.compare(data[0], data[1]);
}
public T[] getData(){
return data;
}
}
in which a Comparator resides,then I defined a Norwich keeping a field order and setter and getter of it, finally there's a method used to implement the compare(T t1,T t2) in Comparator.
public class Norwich {
private int order;
public Norwich(int o) {
order = o;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public int compareOrder(Norwich n) {
if (order > n.getOrder()) {
return 2;
} else if (order == n.getOrder()) {
return 0;
} else {
return -3;
}
}
}
then here comes the main method
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
norwichYxj.addItem(new Norwich(9));
norwichYxj.addItem(new Norwich(1));
System.out.println(norwichYxj.sort());
so what I'm interested in is that, why does not the method compareOrder keep the same parameters as the compare in Comparator but it can still work correctly?
It is simple. You have passed through the constructor your implementation of the Comparator to be used for comparing.
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
Remember Comparator is nothing else than an interface. Since it is a functional interface, it can be represented through a lambda expression or a
method reference (as you did). The way you can pass the Comparator in the full form is as follows. Note the usage of the compareOrder method:
Yxj<Norwich> norwichYxj = new Yxj<>(new Comparator<>() {
#Override
public int compare(Norwich o1, Norwich o2) {
return o1.compareOrder(o2); // usage of compareOrder
}
});
This can be shortened to a lambda expression:
Yxj<Norwich> norwichYxj = new Yxj<>((o1, o2) -> o1.compareOrder(o2));
It can be shortened again to a method reference:
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
Now you can see it can be represented in this way though the method compareOrder accepts only one formal parameter. The first parameter of the Comparator#compare method is the one invoking the compareOrder method and the second parameter is the one being passed to the compareOrder method.
Learn more here: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Additionally, the classes you have constructed look a bit odd. Though the other answer doesn't in fact answer your question, it can lead you to a better code: Implementing a functional interface via method reference
class Yxj
The paramter T of your class Yxj should have more restrictions if you want to compare/sort in this class with T then say T must be comparable.
If your T array grows then don't implement your own growing array but use ArrayList instead which does that for you
If you do the first you don't need the Comperator anymore
Your methode sort only sorts the first and second element so you will get problems. If the data is shorter you will get an ArrayIndexOutOfBoundsException if it is longer it won't sort the rest of elements. So with a Collection you could simple use Collections.sort(data);
public class Yxj<T extends Comparable<T>> {
private final List<T> data;
public Yxj() {
this.data = new ArrayList<>();
}
public void addItem(T t){
data.add(t);
}
public void sort(){
Collections.sort(data);
}
public List<T> getData(){
return data;
}
public void print(){
System.out.println(data);
}
}
class Norwich
If you done the above know your Norwich class must implement the Comparable interface so you can compare Norwich instances with the methode compareTo which also will be called each time you or the API ask directly or indirectly to compare to Norwich instances like for sorting ect.
public class Norwich implements Comparable<Norwich> {
private int order;
public Norwich(int o) {
this.order = o;
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
#Override
public int compareTo(Norwich other) {
return this.order - other.order;
}
#Override
public String toString() {
return "Norwich{" +
"order=" + order +
'}';
}
}
Main
Done? Perfect, then your main could be looks like this
public static void main(String[] args) {
Yxj<Norwich> norwichYxj = new Yxj<>();
norwichYxj.addItem(new Norwich(9));
norwichYxj.addItem(new Norwich(1));
norwichYxj.sort();
norwichYxj.print();
}
I'm trying to do my current project at my university, and I'm given an abstract class Value, and I'm needed to change basic types: int, string, object(map) and array(list) into Value. Value is made into an abstract constructor, and I need to create four different extended classes from Value. Each extended class will be able to get one of the types and convert into Value. added is the code I made for the get method, I want to know if it's possible to return the Value as it is below...
public class Number extends Value {
private Number k;
public Number(Number k)
{
super();
this.k = k;
}
public Value get(int i) {
this.k=i;
return this;
}
}
The following is the super class given by the university...
public abstract class Value
{
public abstract Value get(int i);
public abstract Value get(String s);
}
You can use some thing like this
public abstract class Value {
public abstract Value get(int i);
public abstract Value get(String s);
}
public class Number extends Value {
private Number k;
private Object o;
public Number(Number k) {
super();
this.k = k;
}
#Override
public Value get(int i) {
this.k.o = i;
return this;
}
#Override
public Value get(String s) {
this.k.o = s;
return this;
}
}
I want to have a method in an interface that returns a class whose type is not defined in the package. The implementing class will then return a specific type. I can see at least 3 methods how I can do this, shown below as fn1, fn2 and fn3. In all cases there is some form of unchecked cast. Is any of these methods preferred? or is there something better? (assume that the interface I1 and the method dostuff are in some other jar package and do not have access to the Test or the Integer class)
public class Myclass {
public interface I1
{
Object fn1();
<T> T fn2();
<T> T fn3();
}
public class Test implements I1
{
#Override
public Integer fn1() {
return new Integer(1);
}
#Override
public <T> T fn2() {
return (T) new Integer(2); //requires cast to T
}
#Override
public Integer fn3() { //automatic unchecked conversion to T in return value
return new Integer(3);
}
}
public static void main(String[] args) {
Myclass c = new Myclass();
I1 t = c.new Test();
Integer i = (Integer) t.fn1(); //cast required here since I1.fn1() returns Object
Integer j = t.fn2();
Integer k = t.fn3();
dostuff(t);
}
static void dostuff(I1 p)
{
Object i = p.fn1();
Object j = p.fn2();
Object k = p.fn3();
}
}
Can't you use generics with the Interface? Like
public interface I1<T> {
T fn1();
// etc
}
Then there's no casting required when you refer to T.
That's what I prefer, at least. You can then also of course specify what you want T to be using
<T extends myInterface>
I would do it this way
public interface I1<T> {
T fn1();
}
public class Test implements I1<Integer> {
#Override
public Integer fn1() {
return new Integer(1);
}
}
public static void main(String[] args) {
Myclass c = new Myclass();
I1<Integer> t = c.new Test();
Integer i = t.fn1(); <-- no cast
}
Very simple question, Im implementing a array enumeration class but cannot remember how to get the correct type back on the nextElement() method. The code is as follows...
public class ArrayEnumeration<Object> implements Enumeration<Object> {
private Object[] data;
private int n = 0;
public ArrayEnumeration(Object[] data) {
this.data = data;
}
#Override
public boolean hasMoreElements() {
return n < data.length;
}
#Override
public Object nextElement() {
n++;
return data[n - 1];
}
}
so object returned from the nextElement method should be the type that was defined when the class was created. I just cannot remember how to do it. So annoying!!!
Many thanks in advance.
Check out the source code of java.util.List for an example:
public interface List<E> extends Collection<E> {
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/List.java
Your methods then use the generic type:
public boolean add(E e);
public E get(int index);
All from the source of the java.util.List..
So in your case:
public class ArrayEnumeration<E> implements Enumeration<E> {
...
#Override
public E nextElement() {
n++;
return data[n - 1];
}
}
Use a type parameter:
public class ArrayEnumeration<T>
implements Enumeration<T>
{
private T[] data;
public ArrayEnumeration(T[] data)
{
this.data = data;
}
// ...
public T nextElement() {}
}
Also, you should consider using Iterator instead. But in any event, arrays implement Iterable, so why are you doing this?
I am trying to understand Java Iterator and Iterable interfaces
I am writing this class
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
It seems to be working.
Should I have:
Myclass implements Iterable<Stirng>, Iterator<String> {
}
Or I should put MyClassIterator outside MyClass as
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Which one is better?
You should almost never implement both Iterable and Iterator in the same class. They do different things. An iterator is naturally stateful - as you iterate using it, it has to update its view of the world. An iterable, however, only needs to be able to create new iterators. In particular, you could have several iterators working over the same original iterable at the same time.
Your current approach is pretty much okay - there are aspects of the implementation I'd change, but it's fine in terms of the separation of responsibilities.
You were on track with your first try. MyClass only needs to implement Iterable<String>, which in turn requires you to provide an Iterator<String> implementation to return from Iterable<String>.iterator().
There's no need to put the MyClassIterator outside of MyClass because in most cases you will never even need to directly use the Iterator<String> (it's used implicitly by the for .. in .. syntax on Iterable<String>s), and in all other cases the interface is sufficient unless you actually add additional behavior to the implementation (which you likely won't ever need to do).
Here's how I'd do it, see comments inlined:
import java.util.Iterator;
class MyClass implements Iterable<String>{
public String[] a=null; //make this final if you can
public MyClass(String[] arr){
a=arr; //maybe you should copy this array, for fear of external modification
}
//the interface is sufficient here, the outside world doesn't need to know
//about your concrete implementation.
public Iterator<String> iterator(){
//no point implementing a whole class for something only used once
return new Iterator<String>() {
private int count=0;
//no need to have constructor which takes MyClass, (non-static) inner class has access to instance members
public boolean hasNext(){
//simplify
return count < a.length;
}
public String next(){
return a[count++]; //getting clever
}
public void remove(){
throw new UnsupportedOperationException();
}
};
}
}
You should not do Myclass implements Iterable<String>,Iterator<String>{ since iterators are single-use. With the exception of list iterators, there's no way to return them to the start.
Incidentally, you can skip the
MyClass myClass;
public MyClassInterator(MyClass m){
myclass=m;
}
and instead of referencing
myClass
reference
MyClass.this
Your inner class is not static, so MyClass.this will reference the instance of the enclosing class that created it.