Java object to copy:
public class InfoDtcEx implements Serializable {
private static final long serialVersionUID = 1L;
private String infoCall="";
private String infoNotCall="";
private String infoTarget="";
private String infoTotal="";
private String infoValue="";
private ArrayList<String> valueList;
public InfoDtcEx(String infoCall, String infoNotCall,
String infoTarget, String infoTotal, String infoValue) {
this.infoCall = infoCall;
this.infoNotCall = infoNotCall;
this.infoTarget = infoTarget;
this.infoTotal = infoTotal;
this.infoValue = infoValue;
this.infoValueBefore = this.infoValue;
}
public InfoDtcEx(InfoDtc infoDtc) {
this.infoCall = infoDtc.getinfoDtcCall();
this.infoNotCall = infoDtc.getinfoDtcNotCall();
this.infoTotal = infoDtc.getinfoDtcTotal();
this.infoValue = infoDtc.getinfoDtcValue();
this.infoValueBefore = this.infoValue;
}
//getters and setters
}
I tried Using below method to deep copy as suggested at How to copy elements from an ArrayList to another one NOT by reference?:
private ArrayList<InfoDtcEx> copyInfoList(ArrayList<InfoDtcEx> infoListExChanged) {
infoListExChanged.clear();
for (int i = 0; i < infoListEx.size(); i++) {
String infoCall = infoListEx.get(i).getinfoCall();
if(infoCall != "Yes") {
infoListExChanged.add(infoListEx.get(i));
}
}
return infoListExChanged;
}
But, this is changing the actual list infoListEx as well.
You are not performing the deep copy as suggested in the post you linked to.
That post had the following line in the accepted answer :
copia.add(new Articulo_Venta(av.get(i)));
Notice the construction of the new Articulo_Venta. Your code is not calling new.
So try changing your line where you are adding to the list to create a new object, so :
infoListExChanged.add(new InfoDtcEx(infoListEx.get(i)));
Related
EasyExcel is a tool dealing with EXCEL file, which can read or write a excel file。
EasyExcel.write(fileName, DemoData.class)
.sheet("sheet1")
.doWrite(() -> {
// no comment
return data();
});
DemoData.java
public class DemoData {
#ExcelProperty("title1")
private String string;
#ExcelProperty("title2")
private Date date;
#ExcelProperty("title3")
private Double doubleData;
/**
* ignore this field
*/
#ExcelIgnore
private String ignore;
}
Method data() returns a List which contains type DemoData
private List<DemoData> data() {
List<DemoData> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setString("String" + i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}
In method EasyExcel.write, I can make it with ASM dynamically for DemoData.class which is the List in method data(). Does Java support this?
I am working in Java and I want to make a deep copy of a MoleculeDTO object. I tried to make a copy constructor too, but it is not working and it is refering to the initial object.
public class MoleculeDTO {
private int ID;
private String name;
private List<AtomDTO> atoms = new ArrayList<>();
private int nrAtoms =0;
public MoleculeDTO(String name, List<AtomDTO> atoms, int nrAtoms) {
this.name = name;
this.atoms = atoms;
this.nrAtoms = nrAtoms;
}
public MoleculeDTO(MoleculeDTO molecule) {
this(molecule.getName(), molecule.getAtoms(), molecule.getNrAtoms());
}
...getter, setter
}
Here is class AtomDTO.
public class AtomDTO{
private int ID;
private String name;
private String symbol;
private int nrOfBonds;
private List<BondDTO> bonds = new ArrayList<>();
private int type;
private AnchorNode anchorNode;
public AtomDTO(String name, String symbol, int nrOfBonds, List<BondDTO> bonds, int type) {
this.name = name;
this.nrOfBonds = nrOfBonds;
this.bonds = bonds;
this.type = type;
}
public AtomDTO(AtomDTO copyAtom) {
this(copyAtom.getName(),copyAtom.getSymbol(), copyAtom.getNrOfBonds(), copyAtom.getBonds(), copyAtom.getType());
}
...getter, setter
}
Here is class BondDTO.
public class BondDTO {
private int ID;
private int otherAtomID;
private int otherAtomType;
private int bondType;
public BondDTO(int otherAtomID, int otherAtomType, int bondType) {
this.otherAtomID = otherAtomID;
this.otherAtomType = otherAtomType;
this.bondType = bondType;
}
public BondDTO(BondDTO copyBond) {
this(copyBond.getOtherAtomID(), copyBond.otherAtomType, copyBond.bondType);
}
...getter, setter
}
Your copy constructors are just doing shallow copies of each field. That's fine for strings because they're immutable, and it's fine for ints because they're primitive (which means they lack identity and are immutable). In those cases, there is no important difference between shallow and deep copies. But it doesn't work in general for lists because lists can be mutable and so can their elements. So instead of just pointing at the same list, you need to make a new list and deep copy each element of the original list into the new one.
Use this helper method to make deep copies of any lists:
static <T> List<T> deepCopyList(List<T> list, UnaryOperator<T> deepCopyElement) {
return list.stream().map(deepCopyElement).collect(
Collectors.toCollection(ArrayList::new)
);
}
Like so:
public AtomDTO(AtomDTO that) {
this(that.getName(), that.getType(), deepCopyList(that.getBonds(), BondDTO::new));
}
With this class:
public class MyClass implements Comparable<MyClass> {
private String status;
private String name;
private String firstName;
#Override
public int compareTo(MyClass o) {
return 0;
}
}
I'd like to sort a list of MyClass objects with this order:
Firstly, status = "open", then "working" then, "close"
Secondly, name = "toto", then "titi"
Finally, firstName = "tutu", "tata"
How can I do this with the Comparable interface ?
I would do this like so: first define a set of lists which define the order for each field:
private static List<String> statusOrder = Arrays.asList("open", "working", "close");
private static List<String> nameOrder = Arrays.asList("toto", "titi");
private static List<String> firstNameOrder = Arrays.asList("tutu", "tata");
Then use List.indexOf to get the position of the element in the list, and then simply subtract the results:
#Override
public int compareTo(MyClass o) {
final int statusComp = statusOrder.indexOf(status) - statusOrder.indexOf(o.status);
if (statusComp != 0) return statusComp;
final int nameComp = nameOrder.indexOf(name) - nameOrder.indexOf(o.name);
if (nameComp != 0) return nameComp;
return firstNameOrder.indexOf(firstName) - firstNameOrder.indexOf(o.firstName);
}
The issue with this approach is that indexOf will return -1 if the element is not in the list. You would need to define the behaviour in the case where MyClass contains non-standard values (perhaps it will never happen).
I have the following loop in a controller class:
for (int i = 0; i <= locationArr.length - 1; i++) {
data.put(idArr[i], locationArr[i]);
locationBean.setLocation_name(locationArr[i]);
}
My Bean looks like :
public class LocationBean {
private String region_id;
private String region_name;
private String location_id;
private String location_name;
//getters and setters
}
I am trying to set location_name as setLocation_name(locationArr[i]);
But only getting last values of the loop [i] is being assigned.
If you like to have multiple location names you can do that by e.g. a List or more general any Collection if order does not matter.
Here an example:
public class LocationBean {
private String region_id;
private String region_name;
private String location_id;
private List<String> locationNames = new ArrayList<>();
//getters and setters
public List<String> getLocationNames() {
return locationNames;
}
}
usage in your loop:
locationBean.getLocationNames().add(locationArr[i]);
I did not refactor all your example code to be complient to the java naming convention. You should name your variables in camel case.
Either u can create a list of LocationBean objects :
ArrayList <LocationBean> locationBeanList = new ArrayList <LocationBean>)();
for (int i = 0; i <= locationArr.length - 1; i++) {
data.put(idArr[i], locationArr[i]);
locationBean = new LocationBean();
locationBean.setLocation_name(locationArr[i]);
locationBeanList.add(locationBean);
}
Or, u can create list of locations in single location bean
public class LocationBean {
private String region_id;
private String region_name;
private String location_id;
private List<String> location_name_list = new ArrayList<String>();
//getters and setters
}
List<String> locationList = new ArrayList <String>();
for (int i = 0; i <= locationArr.length - 1; i++) {
data.put(idArr[i], locationArr[i]);
locationList.add(locationArr[i]);
}
locationBean.setLocation_name_list(locationList );
LocationBean with a List
You want to store every location name, not set ONE value. So you want a method addLocationName store it into a Collection
locationBean.addLocationName(locationArr[i]);
That method is simple, it will add every String into a List<String>
private List<String> locationsName;
private List<String> locationsId;
public LocationBean (){
locationsName = new ArrayList<String>();
locationsId= new ArrayList<String>();
}
public boolean addLocationName(string locationName){
return this.locationsName.add(locationName);
}
public boolean addLocationId(string locationId){
return this.locationsId.add(locationId);
}
Of course, you would need to do the same with location_id, so a Bean would be smarter :
public class Location{
private String id;
private String name;
public Location(String id, String name){ ... }
//constructor and getter
}
and simply use a List<Location> instead. That way, both id and name are stored together.
public boolean addLocation(Location location){
return this.locations.add(location);
}
or passing the values
public boolean addLocation(String id, String name){
return this.locations.add(new Location(id, name));
}
List of LocationBean
Or your bean should only have one location and then this is in your loop that you need to store every instance of LocationBean into a List<LocationBean> (don't forget to create a new instance each time`
List<LocationBean> locations = new ArrayList<>();
for (int i = 0; i <= locationArr.length - 1; i++) {
locationBean = new LocationBean(); //new instance each time
locationBean.setLocation_name(locationArr[i]);
locations.add(locationBean); //add into the list
}
I am trying to create a class that will create matrices by taking an array as an input (among other things). This array will be assigned to a record (Record9). However I am getting this error when trying to compile. You can find my code below:
public class Matrix3x3flat {
private class Record9 {
public long r1c1;
public long r1c2;
public long r1c3;
public long r2c1;
public long r2c2;
public long r2c3;
public long r3c1;
public long r3c2;
public long r3c3;
}
private Record9 mat;
public Record9(long[] arr) {
Record9 this.mat = new Record9();
this.mat.r1c1 = arr[0];
this.mat.r1c2 = arr[1];
this.mat.r1c3 = arr[2];
this.mat.r2c1 = arr[3];
this.mat.r2c2 = arr[4];
this.mat.r2c3 = arr[5];
this.mat.r3c1 = arr[6];
this.mat.r3c2 = arr[7];
this.mat.r3c3 = arr[8];
return this.mat;
}
}
I don't understand the problem but I do suspect it has something to do with me not properly referencing this.mat in the return statement.
Well, few things I notice. Edit: as mentioned below, constructor name needs to be the same as class name.
2) Why are you re declaring mat as a type of Record9. You already set it up top as a type of Record9, no need to define it again, you can just say this.mat = whatever it needs to be
My idea is you want to create instance of Record9 on public Record9(long[] arr), currently you use return statement i side of constructor it is not allow. so you need to convert that to a method.
try like this :
public class Matrix3x3flat {
private class Record9 {
public long r1c1;
public long r1c2;
public long r1c3;
public long r2c1;
public long r2c2;
public long r2c3;
public long r3c1;
public long r3c2;
public long r3c3;
}
private Record9 mat;
public Record9 instance(long[] arr) {
this.mat = new Record9();
this.mat.r1c1 = arr[0];
this.mat.r1c2 = arr[1];
this.mat.r1c3 = arr[2];
this.mat.r2c1 = arr[3];
this.mat.r2c2 = arr[4];
this.mat.r2c3 = arr[5];
this.mat.r3c1 = arr[6];
this.mat.r3c2 = arr[7];
this.mat.r3c3 = arr[8];
return this.mat;
}
}