There some thing not right going with Cloneable interface - java

public class Tool extends Item {
#Override
public Item clone() throws CloneNotSupportedException
{
return super.clone();
}
}
clone() method is giving me an error:
Cannot directly invoke the abstract method clone() for the type Item
Item class is a abstract class which implements Cloneable interface.

public class CloneTest {
static abstract class Item implements Cloneable {
private boolean stackable;
protected String name;
public Item() {
this.name = new String("Air");
this.stackable = true;
}
public Item(String name) {
this.name = name;
this.stackable = true;
}
public Item(String name, boolean stackable) {
this.name = name;
this.stackable = stackable;
}
public String getName() {
return this.name;
}
public void setName(String n) {
this.name = n;
}
#Override
public boolean equals(Object rhs) {
Item r = (Item) rhs;
return (this.name).equals(r.name);
}
#Override
public int hashCode() {
return this.name.hashCode();
}
public boolean isStackable() {
return this.stackable;
}
public abstract void read(Scanner s);
#Override
public Item clone() throws CloneNotSupportedException {
Object obj = super.clone();
// Add some custom logic here... like initializing few members
return (Item) obj;
}
#Override
public String toString() {
return (" " + this.name);
}
}
public static class Tool extends Item {
#Override
public Item clone() throws CloneNotSupportedException {
return super.clone();
}
#Override
public void read(Scanner s) {
}
}
public static void main(String[] args) throws CloneNotSupportedException
{
Tool tool1 = new Tool();
System.out.println(tool1);
Object tool2 = tool1.clone();
System.out.println(tool2);
System.out.println(tool1 == tool2);
}
}

Related

Java type for multiple bounds generics

I have classes that implements two interfaces and I need to call methods in both interfaces.
This doesn't compile:
List<? extends Vehicle & Fun> list = Arrays.asList(new Car("a"), new Truck("b"), new Car("c"));
However, this works (local variable type inference) and the program runs as expected:
var list = Arrays.asList(new Car("a"), new Truck("b"), new Car("c"));
How do I specify both interfaces for the variable list?
import java.util.Arrays;
import java.util.List;
interface Vehicle {
public boolean canRun();
public void getName();
}
interface Fun {
public boolean isFun();
}
class Car implements Vehicle, Fun {
protected String name;
public Car(String name) {
this.name = name;
}
#Override
public boolean canRun() {
return true;
}
#Override
public boolean isFun() {
return true;
}
#Override
public void getName() {
System.out.println("Car: " + name);
}
}
class Truck implements Vehicle, Fun {
protected String name;
public Truck(String name) {
this.name = name;
}
#Override
public void getName() {
System.out.println("Truck: " + name);
}
#Override
public boolean canRun() {
return true;
}
#Override
public boolean isFun() {
return false;
}
}
public class test {
public static void main(String[] args) {
var list = Arrays.asList(new Car("a"), new Truck("b"), new Car("c"));
// The following line doesn't compile
// List<? extends Vehicle & Fun> list = Arrays.asList(new Car("a"), new Truck("b"), new Car("c"));
list.stream().filter(v -> v.canRun()).filter(v -> v.isFun()).forEach(Vehicle::getName);
}
}

Given a mutable class, how to make immutable a specific object of this class?

I got THIS class which is obviously mutable for every instance I create, but I want to know if there´s
some kind of wrapper (or something) to make just ONE specific object of THIS class immutable. e.g Collections.unmodifiableList(beanList).
class Animal {
private String name;
private String commentary;
public Animal(String nombre, String comentario) {
this.name = nombre;
this.commentary = comentario;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Animal animal = (Animal) o;
return Objects.equals(name, animal.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
public String getName() {
return name;
}
public String getCommentary() {
return commentary;
}
public void setCommentary(String commentary) {
this.commentary = commentary;
}
public void setName(String name) {
this.name = name;
}
}
The only way I am aware of is to instantiate it and override the methods that are able to modify the particular instance:
Animal animal = new Animal("name", "commentary") {
#Override
public void setCommentary(String commentary) {
throw new UnsupportedOperationException("The Animal is immutable");
}
#Override
public void setName(String name) {
throw new UnsupportedOperationException("The Animal is immutable");
}
};
This also satisfied the condition that only one specific instance of the class has a special behavior.
If you need more of them, create a wrapping class that acts as a decorator (isn't exactly). Do not forget to make the class as final otherwise you would be able to override its method in the way I described above and its immutability might break.
Animal animal = new ImmutableAnimal(new Animal("name", "commentary"));
final class ImmutableAnimal extends Animal {
public ImmutableAnimal(Animal animal) {
super(animal.getName(), animal.getCommentary());
}
#Override
public void setCommentary(String commentary) {
throw new UnsupportedOperationException("The Animal is immutable");
}
#Override
public void setName(String name) {
throw new UnsupportedOperationException("The Animal is immutable");
}
}

Restrain the type while inheriting

I created a java project to apply my GraphTheory course and enhance my java skills.
In this project :
I created a class Sommet<S>(Vertex in English) with an attribute Id with a generic type called <S>.
I created a class Arc<S>(Edge in English) with two attributes Sommet(Vertex).
I created a class EnsembleArc which is an HashSet of Arc
I also created a class ArcValue which inherit from Arc and have an int attribute Valeur(Value in English)
Here everything is fine and I dont have any problem.
But then I created a class EnsembleArcValue which inherit from EnsembleArc because every method from EnsembleArc will be useful to EnsembleArcValue.
But I also want EnsembleArcValue to be an HashSet of ArcValue (and I dont want an Arc which is not an ArcValue). And with the inheritance EnsembleArcValue is able to have an "simple" Arc in his Set.
So my question after all this explanation is :
Is there a way for EnsembleArcValue to inherit from EnsembleArc but will only accept an ArcValue in his Set.
Here is an image of The UML Project
I hope it will help to understand my problem (dont look at the bottom).
Here is the code :
public class Sommet<S>
{
//attributes
private S id;
public Sommet(S s)
{
setId(s);
}
public S getId()
{
return id;
}
public void setId(S s)
{
assert s!= null: "Objet null passé en paramètre";
id = s;
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object obj)
{
boolean callback;
if(obj.getClass()!=getClass())
{
callback=false;
}
else
{
if(((Sommet<S>)obj).getId().equals(getId()))
{
callback=true;
}
else
{
callback=false;
}
}
return callback;
}
#Override
public int hashCode()
{
return getId().hashCode();
}
#Override
public String toString()
{
return getId().toString();
}
}
public class Arc<S>
{
private Sommet<S> depart;
private Sommet<S> arrivee;
public Arc(Sommet<S> dep, Sommet<S> arr)
{
setDepart(dep);
setArrivee(arr);
}
#Override
public String toString()
{
String str="("+getDepart().getId()+","+getArrivee().getId()+")";
return str;
}
public Sommet<S> getDepart()
{
return depart;
}
public Sommet<S> getArrivee()
{
return arrivee;
}
public void setDepart(Sommet<S> depart)
{
this.depart = depart;
}
public void setArrivee(Sommet<S> arrivee)
{
this.arrivee = arrivee;
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(Object obj)
{
boolean callback;
if(obj.getClass()!=getClass())
{
callback=false;
}
else
{
if(((Arc<S>)obj).getDepart().equals(getDepart())&&((Arc<S>)obj).getArrivee().equals(getArrivee()))
{
callback=true;
}
else
{
callback=false;
}
}
return callback;
}
#Override
public int hashCode()
{
return getArrivee().hashCode()+getDepart().hashCode();
}
}
public class ArcValue<S,V> extends Arc<S>
{
private V valeur;
public ArcValue (Sommet<S> depart, Sommet<S> arrivee, V valeur)
{
super(arrivee,depart);
this.valeur=valeur;
}
public V getValeur()
{
return valeur;
}
}
import java.util.HashSet;
public class Ensemble<E> extends HashSet<E> implements Cloneable
{
private static final long serialVersionUID = -4354387895748449845L;
public Ensemble ()
{
super();
}
public Ensemble (Ensemble<E> ensemble)
{
for (E e : ensemble)
{
add(e);
}
}
public String toString()
{
StringBuffer str=new StringBuffer("{");
for(E e: this)
{
str=str.append(e.toString()+",");
}
str.setCharAt(str.length()-1, '}');
return str.toString();
}
#SuppressWarnings("unchecked")
#Override
public Ensemble<E> clone()
{
return (Ensemble<E>)super.clone();
}
}
public class EnsembleArc<S> extends Ensemble<Arc<S>>
{
public EnsembleArc(Ensemble<Arc<S>> ensemble)
{
super(ensemble);
}
public EnsembleArc()
{
super();
}
private static final long serialVersionUID = -4099925554493145279L;
public EnsembleSommet<S> listSucc(Sommet<S> sommet)
{
EnsembleSommet<S> XSucc=new EnsembleSommet<S>();
for (Arc<S> arc : this)
{
if (arc.getDepart()==sommet)
{
XSucc.add(arc.getArrivee());
}
}
return XSucc;
}
public EnsembleSommet<S> listPred(Sommet<S> sommet)
{
EnsembleSommet<S> XPred=new EnsembleSommet<S>();
for (Arc<S> arc : this)
{
if (arc.getArrivee()==sommet)
{
XPred.add(arc.getDepart());
}
}
return XPred;
}
public void add(Sommet<S> depart,Sommet<S>arrivee)
{
add(new Arc<S>(depart,arrivee));
}
#Override
public EnsembleArc<S> clone ()
{
return (EnsembleArc<S>)super.clone();
}
}
//import java.util.Collection;
public class EnsembleArcValues<S,V> extends EnsembleArc<S> //implements Collection<ArcValue<S,V>>
{
//TODO faire en sorte que ensembleArcValués ne contienne que des ArcsValue
private static final long serialVersionUID = -7163498825360866323L;
}
And you'll need this one to :
public class EnsembleSommet<S> extends Ensemble<Sommet<S>>
{
public EnsembleSommet()
{
super();
}
public EnsembleSommet(EnsembleSommet<S> ensemble)
{
super(ensemble);
}
private static final long serialVersionUID = 7278825382690341067L;
#Override
public EnsembleSommet<S> clone ()
{
return (EnsembleSommet<S>)super.clone();
}
public Sommet<S> firstSommet()
{
#SuppressWarnings("unchecked")
Sommet<S>[] tab=new Sommet[size()];
return toArray(tab)[0];
}
}
The only way you can achieve this is to make the type of Arc you want part of your generic deceleration. Rename your existing EnsembleArc to AbstractEnsembleArc and change it's generic decleration from < S > to < S, T extends Arc< S > > i.e.:
public abstract class AbstractEnsembleArc<S, T extends Arc<S>> extends Ensemble<T> {
// PUT ALL YOUR LOGIC CURRENTLY IN EnsembleArc HERE
}
Now create a new Class Called EnsembleArc and extend the new abstract class you've added, this new class will work identically to your existing EnsembleArc and class decleration should now look like:
public class EnsembleArc<S> extends AbstractEnsembleArc<S, Arc<S>> {
}
Finally have EnsembleArcValues extend the Abstract class instead of EnsembleArc so that you can declare that it should only accepts ArcValue and not simple Arc, do that like this:
public class EnsembleArcValues<S, V> extends AbstractEnsembleArc<S, ArcValue<S, V>> {
}

How I can convert this Generic Class to a Parcelable?

I want to convert this generic class to a parcelable object, but I don't have very clear the concepts of the issue.
Class:
public class Type<T> implements Parcelable {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
This is what I've tried,. but I know that this is not correct, or maybe this is not complete.
public class Type<T> implements Parcelable {
// T stands for "Type"
private T t;
protected Type(Parcel in) {
}
public void set(T t) { this.t = t; }
public T get() { return t; }
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
public static final Creator< Type > CREATOR = new Creator< Type >() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
}
This is similar approach as vikas kumar but guarantte that you can pass only Parcelable as T parameter so you avoid exception.
public class Type<T extends Parcelable> implements Parcelable {
private T t;
protected Type(Parcel in) {
t = (T) in.readValue(t.getClass().getClassLoader());
}
public static final Creator<Type> CREATOR = new Creator<Type>() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(t);
}
}
Your generic data type may cause runtime error
so make sure you implements Parcelable and also the class you are passing should implement Parcelable otherwise it will cause runtime error.
public class Type<T extends Parcelable> implements Parcelable {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
protected Type(Parcel in) {
final String className = in.readString();
try {
t = in.readParcelable(Class.forName(className).getClassLoader());
} catch (ClassNotFoundException e) {
Log.e("readParcelable", className, e);
}
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(t);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
#Override
public Type createFromParcel(Parcel in) {
return new Type(in);
}
#Override
public Type[] newArray(int size) {
return new Type[size];
}
};
}

how to work with WritableComparator Hadoop

Below are my code snippet for using WritableComparator, but it does not work
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class MovieComparator extends WritableComparator{
public MovieComparator(){
super(Movie.class);
}
#Override
public int compare(WritableComparable o,WritableComparable o2){
System.out.println("in compare");
Movie m = (Movie)o;
Movie m2 = (Movie)o2;
System.out.println(m.compareTo(m2));
return m.movieId.compareTo(m2.movieId);
}
}
public class Movie implements WritableComparable {
Text movieId;
Text movieTitle;
public Movie(Text movieId, Text movieTitle) {
this.movieId = movieId;
this.movieTitle = movieTitle;
}
public Movie(){
}
public String getMovieId() {
return movieId.toString();
}
public void setMovieId(String movieId) {
this.movieId = new Text(movieId);
}
public String getMovieTitle() {
return movieTitle.toString();
}
public void setMovieTitle(String movieTitle) {
this.movieTitle = new Text(movieTitle);
}
#Override
public void readFields(DataInput in) throws IOException {
//movieId = in.read;
movieId.readFields(in);
movieTitle.readFields(in);
}
#Override
public void write(DataOutput out) throws IOException {
//out.writeUTF(movieId);
//out.writeUTF(movieTitle);
movieId.write(out);
movieTitle.write(out);
}
#Override
public int compareTo(Movie o) {
// System.out.println("in compareTo");
int res=movieTitle.compareTo(o.movieTitle);
return res;
}
#Override
public int hashCode(){
return movieId.hashCode();
}
#Override
public boolean equals(Object o){
Movie m=(Movie)o;
return movieId.equals(m.movieId);
}
#Override
public String toString(){
return movieTitle.toString();
}
}
In driver class I am setting the comparator by below line
job.setSortComparatorClass(MovieComparator.class);
Can any body tell me where I am wrong in this at it gives exception below
14/09/08 14:17:03 WARN mapred.LocalJobRunner: job_local_0001
java.io.IOException: Spill failed
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1029)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:691)
at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)
at com.impetus.MovieMapper.map(MovieMapper.java:44)
at com.impetus.MovieMapper.map(MovieMapper.java:1)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:764)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:370)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:212)
I found the issue that Instead of using super(Movie.class), I will have to use super(Movie.class,true). As by sending true, WritableComparator will instantiate the object other wise it will pass null in compare method

Categories

Resources