how do I copy an object containing collections as fields - java

consider the below code:
public class Bid {
private double pe;
private List<ResChar> resourceList;
protected Map<Integer,Integer>scheduleOfSeller ;
public Map<Integer, Integer> getScheduleOfSeller() {
return scheduleOfSeller;
}
public void setScheduleOfSeller(Map<Integer, Integer> scheduleOfSeller) {
this.scheduleOfSeller = scheduleOfSeller;
}
private int bidId;
public int getBidId() {
return bidId;
}
public void setBidId(int bidId) {
this.bidId = bidId;
}
public double getPe() {
return pe;
}
public void setPe(double pe) {
this.pe = pe;
}
public List<ResChar> getResourceList() {
return resourceList;
}
public void setResourceList(List<ResChar> resourceList) {
this.resourceList = resourceList;
}
public Bid(int bidId,double pe, List<ResChar> resourceList){
setBidId(bidId);
setPe(pe);
setResourceList(resourceList);
this.scheduleOfSeller = new HashMap<Integer,Integer>();
}
}
I want to make a copy constructor of the bid like this :
public class BidCopy{
public Bid bid;
public BidCopy(Bid bidBuyer){
List<ResChar> resList = new LinkedList<ResChar>();
for (ResChar elt : bidBuyer.getResourceList()){
ResCharCopy eltCopy = new ResCharCopy(elt);
resList.add(eltCopy.elt);
}
this.bid = bidBuyer;
this.bid.setResourceList(resList);
}
}
The only solution that I know to make such copy is to proceed like follows :
public class BidCopy{
public Bid copy;
public BidCopy(Bid bid){
List<ResChar> resList = new LinkedList<ResChar>();
for (ResChar elt : bid.getResourceList()){
ResCharCopy eltCopy = new ResCharCopy(elt);
resList.add(eltCopy.elt);
}
this.copy = new Bid(bid.getBidId(), bid.getPe(), resList);
}
}
So I want to know if there is any other solution to make a copy of "Bid" Object more effectively ?

I would suggest making a copy constructor for your Bid object (and not a specific class for copying), a Bid is made out of its fields and not methods, like so:
public class Bid {
int ID;
String description;
Object bidStuff;
// ...as before
public Bid(Bid bid) {
this.ID = bid.ID;
this.description = bid.description;
this.bidStuff = bid.bidStuff;
}
public static void main(String[] args) {
List<Bid> original = new ArrayList<>();
// ..populate it
List<Bid> copy = new ArrayList<>(original.size());
for (Bid b : original) {
copy.add(new Bid(b));
}
}
}
You can even make the copy constructor protected or package-protected if you don't want anyone else to mess around with making multiple copies of bids.

There is not. Even though some collections have "copy constructors", these constructors will copy the elements' references, they will not create new elements for you.
You can however "optimize" the list creation itself by submitting the size of the initial list to the constructor:
List<X> newList = new LinkedList<X>(oldList.size());

Related

Populating array in sub class with parent class getter java

Sorry as I know this is obvious but I cant figure it out!
I have a parent class named 'Set', representing a set of a tennis match.
public class Set {
private String set1;
private String set2;
private String set3;
//private Object[] match;
public Set() {
setSet1(set1);
setSet2(set2);
setSet3(set3);
}
public void setSet1(String set1) {
this.set1 = set1;
}
public String getSet1() {
return set1;
}
public void setSet2(String set2) {
this.set2 = set2;
}
public String getSet2() {
return set2;
}
public void setSet3(String set3) {
this.set3 = set3;
}
public String getSet3() {
return set3;
}
public String toString(){
return String.format("set1: %s, set2: %s, set3: %s", set1, set2, set3);
}
}
And a sub class of 'Set' named 'SingleSet', where i try to add the sets into an array named 'game':
public class SingleSet extends Set{
private Object homePlayer;
private Object awayPlayer;
private String[] game;
public SingleSet(Object homePlayer, Object awayPlayer){
super();
game = new String[3];
game[0] = super.getSet1();
game[1] = super.getSet2();
game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
public void setHomePlayer(Object homePlayer) {
this.homePlayer = homePlayer;
}
public Object getHomePlayer() {
return homePlayer;
}
public void setAwayPlayer(Object awayPlayer) {
this.awayPlayer = awayPlayer;
}
public Object getAwayPlayer() {
return awayPlayer;
}
public void setGame(String[] game) {
this.game = game;
}
public String[] getGame() {
return game;
}
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
}
And this is where I am trying to add the Sets from my parents class into my sub class (this is for FXML, so the code is in my controller):
public void submit() {
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
System.out.println(game1);
When I print the result, all my values are null. I tried printing them individually and that worked fine, so I know the 'set1Box.getText()' is working fine.
Again sorry for any obvious rookie error!
I've updated my code and same issue. Thank you for the composition answer, I will need it for my project, but this is a IS-A relationship
Make sure that the toString() methods of the following attributes exist and return a correct string.
It seems as if there is no way to get a String from homePlayer, awayPlayer and all indices of game[x].
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}

How to couple an instance member to a instance method?

I have a class structure like :
public interface DBReader {
public Map<String, String> read(String primaryKey, String valueOfPrimaryKey,
boolean scanIndexForward, boolean consistentRead, int maxPageSize);
public int getA(String ___);
public int getB(String ___);
public int getC(String ___);
}
public class DynamoDBReader implements DBReader {
private DynamoDB dynamoDB;
private String tableName;
private Table table;
private int throughput;
private DynamoDBReader(Builder builder) {
this.throughput = builder.throughput;
this.tableName = builder.tableName;
this.dynamoDB = builder.dynamoDB;
this.table = dynamoDB.getTable(builder.tableName);
if (table == null) {
throw new InvalidParameterException(String.format("Table %s doesn't exist.", tableName));
}
}
#Override
public int getA(String ____) {
read(_________);
}
return ________;
}
#Override
public int getB(String ____) {
read(_________);
}
return ________;
}
#Override
public int getC(String ____) {
read(_________);
}
return ________;
}
#Override
public Map<String, String> read(String primaryKey, String valueOfPrimaryKey, boolean scanIndexForward,
boolean consistentRead, int maxPageSize) {
QuerySpec spec = new QuerySpec()
.withHashKey(primaryKey, valueOfPrimaryKey)
.withScanIndexForward(scanIndexForward)
.withConsistentRead(consistentRead)
.withMaxPageSize(maxPageSize);
ItemCollection<QueryOutcome> items = table.query(spec);
Iterator<Item> itemIterator = items.firstPage().iterator();
Map<String, String> itemValues = new HashMap<String, String>();
while (itemIterator.hasNext()) {
Item item = itemIterator.next();
}
return itemValues;
}
}
#VisibleForTesting
protected void setTable(Table table) {
this.table = table;
}
/**
* Returns a new builder.
*/
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String tableName;
private int throughput;
private DynamoDB dynamoDB;
private Builder() { }
public Builder tableName(String tableName) {
this.tableName = tableName;
return this;
}
public Builder throughput(int throughput) {
this.throughput = throughput;
return this;
}
public Builder dynamoDB(DynamoDB dynamoDB) {
this.dynamoDB = dynamoDB;
return this;
}
public DynamoDBReader build() {
if (tableName == null) {
throw new InvalidParameterException("Table name can't be null.");
}
if (throughput <= 0) {
throw new InvalidParameterException("Throughput should be > 0.");
}
if (dynamoDB == null) {
throw new InvalidParameterException("dynamoDB can't be null.");
}
return new DynamoDBReader(this);
}
}
}
Problem : getA(), getB(), getC() are only valid for specific tableNames. For a table getA() is Valid but getB() and getC() wont make any sense.
How to couple method names with table name so that someone with a table name knows which function is valid.
Solution to create subclasses for different getters doesn't look a great idea to me.
Solution to create subclasses for different getters doesn't look a great idea to me.
Can you please elaborate why?
I hear that all the time, 'I don't like it...', 'This seems ugly...', 'It shouldn't do that'. Reasons for not liking a particular solution should be backed by objective reasons, not personal opinions. Most of the time our intuition as developers tells us that something is wrong when it is actually violating some software development principle. But sometimes it is just plain old personal feeling without any particular logical reason. When that happens I like to get to specifics.
Your solution violates a basic software principle called SRP.
Having table modules will be much better solution.

Can not access members outside

public class TableModel extends AbstractTableModel {
public int page;
public TableModel(Integer p) {
this.page=p;
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
#Override
public int getRowCount() {
return data.size() ;
}
Can not access variable page in getgroup() method it passes 0 to getgroup() method.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Your question is unclear, but I suspect the problem is just that all the instance initializers are being run before the constructor body, so you're seeing the default value for page. You should have something like:
public class TableModel extends AbstractTableModel {
private static final String[] columnNames =
{"groupName","membersCount","previliage"}; // TODO: Fix spelling!
private final int page;
private final List<GroupData> data;
public TableModel(int page) {
this.page = page;
this.data = new DatabaseLayer().getGroup(page);
}
...
}
It's generally a good idea to keep all your instance/static variable declarations in one place (I prefer to keep them at the top, but YMMV) and make them all private to make it easier to reason about how they're used. The main change, however, is moving the new DatabaseLayer ().getGroup(page) code into the constructor.
public class TableModel extends AbstractTableModel {
public int page;
public ArrayList<GroupData> data;
public TableModel(Integer p) {
this.page=p;
this.data = (new DatabaseLayer ()).getGroup(page);
System.out.println("mm"+page);
}
public void pudata() {
System.out.println(page);
}
//System.out.println("model "+page);
private String[] columnNames = {"groupName","membersCount","previliage"};
#Override
public int getRowCount() {
return data.size() ;
}
Refresh your data field every time when you assign a new value to the page field.
public TableModel(int p) {
setPage(p);
}
public void setPage(int p) {
this.page = p;
this.data = new DatabaseLayer ().getGroup(page);
}
This is absolute correct because:
public int page;
default value for page is 0 because its int.
public ArrayList<GroupData> data = (new DatabaseLayer ()).getGroup(page);
Is a variable initialization so before initialization of page you are passing it into .getGroup(page) so default value will pass in that case.
So you have to call getGroup(int) method after page being initialized, one way can be following:
private final List<GroupData> data;
public TableModel(Integer p) {
this.page = p;
this.data = new DatabaseLayer().getGroup(page);
System.out.println("mm"+page);
}

Java: How to design collection using a superclass

This is a practical question, but I am not sure if it has a practical answer. If you have a superclass with let's say 10 subclasses, what is the most simple way to put those 10 subclasses in a collection? Right now (this may be bad design), I have put them in a static collection field in the superclass.
The motivation for this question, however, came because I had obtained the identity of one of the fields of one of the subclasses, but I needed a reference to a different field in the same subclass.
For instance, let's say the subclass has the following fields:
public class SampleSubClass extends SampleSuperClass{
...
private Object1 o_1;
private Object2 o_2;
private Object3 o_3;
...
}
Somewhere else in the program, I have only the identity of o_2, and I wanted to get at o_3.
In theory, there might be an easier way than having to put all of the instances of SampleClass in a collection somewhere. For instance, perhaps in my dreams, there is a software language out there, where the superclass DOES carry information about its subclasses, and the superclass serves as a collection in and of itself.
But nevermind that. To me now, it seems like a good way to put the collection somewhere in the program, is to use a hashmap/hashtable, and to use it as a static member of the superclass.
Please tell me there is a better way. Is there any way to reference field A in an object by having only a reference to field B in an object?
For instance, say I have an ActionPerformed method, it has a source object that is contained in the ActionEvent object parameter. How would I find the instance of the class that owned/contained that source object? What is the best way to design this?
There is no native way to find the owner of a field given the object the field references. The JVM records the number of references pointing to each object so it can do garbage collection, but it doesn't keep track of the owners of the references.
You can store the values of all the fields in a Map which maps them to their owners:
import java.util.*;
public class Super
{
static Map<Object, Super> owners = new IdentityHashMap<Object, Super>();
// IdentityHashMap will not work with primitives due to autoboxing,
// but HashMap requires all field values to have sensible implementations
// of hashCode() and equals().
/** Gets the owner associated with a field. */
public static Object getOwner(Object field)
{
return owners.get(field);
}
/** Establishes ownership over a field. */
protected void own(Object field)
{
owners.put(field, this);
}
/** Removes an ownership, but only if this is the owner. */
protected void disown(Object field)
{
if (owners.get(field) == this) owners.remove(field);
}
/** Shorthand for disown(oldField); own(newField). */
protected <T> T change(T oldField, T newField)
{
disown(oldField);
own(newField);
return newField;
}
}
public class SubA extends Super
{
protected String s;
protected Integer i;
public SubA(String aString, Integer anInt) { setS(aString); setI(anInt); }
public void setS(String aString) { s = change(s, aString); }
public void setI(Integer anInt) { i = change(i, anInt); }
public String toString() { return "SubA(" + s + "," + i + ")"; }
}
public class SubB extends Super
{
protected Object o;
public SubB(Object anObject) { setO(anObject); }
public void setO(Object anObject) { o = change(o, anObject); }
public String toString() { return "SubB(" + o + ")"; }
}
public class Demo
{
public static void main(String[] args)
{
String s1 = "String1", s2 = "String2", s3 = "String3";
Integer i1 = 111, i2 = 222;
Object o1 = new Object(), o2 = new Object();
SubA a1 = new SubA(s1, i1), a2 = new SubA(s2, i2);
SubB b = new SubB(o1);
p("s1 owner = %s", Super.getOwner(s1)); // SubA(String1,111)
p("s2 owner = %s", Super.getOwner(s2)); // SubB(String2,222)
p("s3 owner = %s", Super.getOwner(s3)); // null
p("i1 owner = %s", Super.getOwner(i1)); // SubA(String1,111)
p("i2 owner = %s", Super.getOwner(i2)); // SubA(String2,222)
p("o1 owner = %s", Super.getOwner(o1)); // SubB(java.lang.Object#...)
p("o2 owner = %s", Super.getOwner(o2)); // null
p("s1 -> s3, o1 -> o2");
a1.setS(s3);
b.setO(o2);
p("s1 owner = %s", Super.getOwner(s1)); // null
p("s3 owner = %s", Super.getOwner(s3)); // SubA(String3,111)
p("o1 owner = %s", Super.getOwner(o1)); // null
p("o2 owner = %s", Super.getOwner(o2)); // SubB(java.lang.Object#...)
}
static void p(String fmt, Object... args)
{
System.out.format(fmt, args);
System.out.println();
}
}
Or you could make the field values themselves maintain a reference to their owner, either through inheritance or using a wrapper class:
public class OwnableObject
{
protected Object owner;
public OwnableObject(Object anOwner) { owner = anOwner; }
public Object getOwner() { return owner; }
public void setOwner(Object anOwner) { owner = anOwner; }
}
public class MyString extends OwnableObject
{
protected String str = null;
public MyString(Object anOwner) { super(anOwner); }
public String toString() { return str; }
public void set(String aString) { str = aString; }
}
public class FieldWrapper<E> extends OwnableObject
{
protected E value = null;
public FieldWrapper(Object anOwner) { super(anOwner); }
public E getValue() { return value; }
public void setValue(E aValue) { value = aValue; }
}
public class Demo
{
protected MyString s = new MyString(this);
protected FieldWrapper<Integer> i = new FieldWrapper<Integer>(this);
public void setS(String aString) { s.set(aString); }
public void setI(int anInt) { i.setValue(anInt); }
public String toString() { return "Demo(" + s + "," + i.getValue() + ")"; }
public static void main(String[] args)
{
Demo d1 = new Demo();
Demo d2 = new Demo();
MyString f1 = d1.s;
FieldWrapper<Integer> f2 = d1.i;
OwnableObject f3 = d2.s;
OwnableObject f4 = d2.i;
d1.setS("one");
d2.setS("two");
d1.setI(1000);
d2.setI(2000);
p("f1 = %s, owner = %s", f1, f1.getOwner());
p("f2 = %d, owner = %s", f2.getValue(), f2.getOwner());
p("f3 = %s, owner = %s", f3, f3.getOwner());
p("f4 = %s, owner = %s", f4, f4.getOwner());
}
static void p(String fmt, Object... args)
{
System.out.format(fmt, args);
System.out.println();
}
}
Answering your direct question: how to easily define a collection containing a given set of classes?
public class ClassA {
private final List<Class<? extends a>> knownSubclasses = Arrays.asList(ClassB.class, ClassC.class);
};
class ClassB extends ClassA {}
class ClassC extends ClassA {}
Answering your motivation: how to access a field in a subclass without declaring it for the super class?
public class SomeSuperclass {
protected Object3 getObject3() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
}
public class SomeSubclass extends SomeSuperclass {
private final Object3 object3 = null;
#Override
protected Object3 getObject3() { return object3; }
}
Maybe recognize instances having an object3 by the use of interfaces
public interface MyClassWithObject3 { Object3 getObject3(); }
...
void someOperation(SomeSuperclass that) {
if (that instanceof MyClassWithObject3) { ... }
}
You could also use named properties
void someOperation(SomeSuperClass that) {
Object3 object3 = that.getProperty("object3");
}

Java class with pairs of static array values

I am creating a certain class using
MyClass class1 = new MyClass(ClassA.StaticSet1, ClassA.StaticCoef1);
MyClass class2 = new MyClass(ClassB.StaticSet1, ClassB.StaticCoef1);
so I wanted to gather all these static values in one class and call them using something like
MyClass class1 = new MyClass(TopClass.Obj1);
MyClass class2 = new MyClass(TopClass.Obj2);
where Obj1 and Obj2 are static entities containing the abovementioned pairs of values.
the closest thing I could do was creating static classes inside TopClass and extending one base class
so I got this ugly implementation
Public class TopClass{
public static class Base{
public String set[];
public double coef[];
public Base(s, c){
set = s;
coef = c;
}
}
public static class Obj1 extends Base{
public static String set[] = {"a","b","C"};
public static double coef[]= {1,2,3};
public Obj1(){
super(set, coef);
}
}
public static class Obj2 extends Base{
public static String set[] = {"x","y","z"};
public static double coef[]= {11,12,13};
public Obj2(){
super(set, coef);
}
}
}
then I call them with
Myclass class1 = new MyClass((TopClass.Base)(new TopClass.Obj1());
Myclass class2 = new MyClass((TopClass.Base)(new TopClass.Obj2());
but this wasn't what I exactly wanted because the class became cumbersome especially that I will be creating many of these entries.
any insight would be much appreciated :)
thanks,
Hani
This would be a great place to use a Factory pattern. Maybe something like:
public class SetCoefProvider {
private String[] set;
private double[] coef;
public SetCoefProvider(String[] set, double[] coef) {
this.set = set;
this.coef = coef;
}
public String[] getSet() {
return set;
}
public double[] getCoef() {
return coef;
}
}
public class SetCoefProviderFactory {
public static SetCoefProvider createObj1Provider() {
return new SetCoefProvider(new String[] {"a", "b", "c"}, new double[] {1,2,3});
}
public static SetCoefProvider createObj2Provider() {
return new SetCoefProvider(new String[] {"x", "y", "z"}, new double[] {11,12,13});
}
}
and then if you really want them to be singletons, you can always do something like:
public class SingletonSetCoefProviders {
private static SetCoefProvider obj1Provider, obj2Provider;
static {
obj1Provider = SetCoefProviderFactory.createObj1Provider();
obj2Provider = SetCoefProviderFactory.createObj2Provider();
}
public static SetCoefProvider getObj1Provider() {
return obj1Provider;
}
public static SetCoefProvider getObj2Provider() {
return obj2Provider;
}
}
I will be creating many of these entries. any insight would be much appreciated :)
The idea is that with statics, you don't want to make many of them, that's the whole point of a static thing. Rethink and/or re-ask with more context about your goals, what you're intending to accomplish isn't clear.
i would encapsulates the Object1 and object2, the why is to make sure that they are available to use and access, at least they are not null. see below:
public static TopClass(){
private static Object obj01 = null;
private static Object obj02 = null;
public Object getObj01(){
if(obj01 == null){
obj01 = new Object();
}
return (obj01);
}
public Object getObj02(){
if(obj02 == null){
obj02 = new Object();
}
return (obj02);
}
}
or in your case the objects are in array tipe [],.
i don't get the static part. why not do something like:
import java.util.*;
interface Foo {
String[] set();
double[] coef();
}
class FooImpl1 implements Foo {
#Override public String[] set() {
return set;
}
#Override public double[] coef() {
return coef;
}
String set[]={"a","b","C"};
double coef[]={1,2,3};
}
class FooImpl2 implements Foo {
#Override public String[] set() {
return set;
}
#Override public double[] coef() {
return coef;
}
String set[] = {"x","y","z"};
double coef[]= {11,12,13};
}
interface Bar {
Foo foo1=new FooImpl1();
Foo foo2=new FooImpl2();
}
public class So9577640 {
public static void main(String[] args) {
Foo foo1=new FooImpl1();
System.out.println(Arrays.asList(foo1.set()));
Foo foo2=new FooImpl2();
System.out.println(Arrays.asList(foo2.set()));
System.out.println(Arrays.asList(Bar.foo1.set()));
System.out.println(Arrays.asList(Bar.foo2.set()));
}
}

Categories