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?
Related
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)));
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 have four ArrayLists. I want to sort one of them alphabetically with case ignored and do the same changes in the other three ArrayLists.
ArrayList<String> arrPackage = new ArrayList<>();
ArrayList<String> arrPackageDates = new ArrayList<>();
ArrayList<String> arrPackageDuration = new ArrayList<>();
ArrayList<String> arrPackageFileSize = new ArrayList<>();
// Code to add data to ArrayLists (data is not coming from sqlite database)
...
// Code to sort arrPackage alphabatically with case ignored
Collections.sort(arrPackage, new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
but how do I know which indexes were changed?
One approach would be to create a wrapper object Package which contains the four types of metadata which appears in the four current lists. Something like this:
public class Package {
private String name;
private String date;
private String duration;
private String fileSize;
public Package() {
// can include other constructors as well
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// other getters and setters
}
Then sort using a custom comparator which works on Package objects:
List<Package> packages = new ArrayList<>();
Collections.sort(packages, new Comparator<Package>() {
#Override
public int compare(Package p1, Package p2) {
String name1 = p1.getName();
String name2 = p2.getName();
return name1.compareToIgnoreCase(name2);
}
});
As a general disclaimer, the above operation would most likely be performed must more efficiently in a database. So if your data is ultimately coming from a database, you should try to do such heavy lifting there.
A simple easy way would be backing up your ArrayList.
ArrayList<String> backupPackage = arrPackage;
And then use your code to sort the array. Then use a for loop to compare the two arrays.
for (int i = 0; i < backupArray.size(); i++) {
if (!aar.get(i).equals(aar.get(i))) { // then the item has been changed
// ... YOUR CODE
// at this point you know which indexes have been changed and can modify your other arrays in any way you need
}
}
I used this approach:
ArrayList<String> backupPackage = new ArrayList<>();
ArrayList<String> backupPackageDates = new ArrayList<>();
ArrayList<String> backupPackageDuration = new ArrayList<>();
ArrayList<String> backupPackageFileSize = new ArrayList<>();
for(int j=0;j<arrPackage.size();j++) {
backupPackage.add(arrPackage.get(j));
}
for(int j=0;j<arrPackageDates.size();j++) {
backupPackageDates.add(arrPackageDates.get(j));
}
for(int j=0;j<arrPackageDuration.size();j++) {
backupPackageDuration.add(arrPackageDuration.get(j));
}
for(int j=0;j<arrPackageFileSize.size();j++) {
backupPackageFileSize.add(arrPackageFileSize.get(j));
}
Collections.sort(arrPackage, new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2);
}
});
int newindex;
for(int i=0; i<backupPackage.size(); i++) {
newindex = backupPackage.indexOf(arrPackage.get(i));
if(newindex != i) {
arrPackageDates.set(i, backupPackageDates.get(newindex));
arrPackageDuration.set(i, backupPackageDuration.get(newindex));
arrPackageFileSize.set(i, backupPackageFileSize.get(newindex));
}
}
backupPackage.clear();
backupPackageDuration.clear();
backupPackageDuration.clear();
backupPackageFileSize.clear();
Hi I'm having some trouble getting started with a problem in a Java course learning Swing and starting on JTables and getting data into them. It's going to be hard to explain so I'm just going to post the code I was given, along with the question.
The question is:
The getData() method needs to return an Object[][] containing the data represented by the class.
The first class is MusicAlbum
class MusicAlbum {
private String id;
private String name;
private String genre;
private boolean isCompilation;
private int track_count;
public MusicAlbum(String id, String name, String genre, boolean isCompilation, int track_count) {
this.id = id;
this.name = name;
this.genre = genre;
this.isCompilation = isCompilation;
this.track_count = track_count;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getGenre() {
return genre;
}
public boolean isCompilation() {
return isCompilation;
}
public int getTrackCount() {
return track_count;
}
public boolean equals(Object obj) {
if (obj instanceof MusicAlbum)
return this.id.equalsIgnoreCase(((MusicAlbum)obj).id);
return super.equals(obj);
}
}
The class I have to implement the methods in is MusicDataObject (at the bottom)
import java.util.Random;
import java.util.Scanner;
public class MusicDataObject {
private List<MusicAlbum> albums = new ArrayList<>();
private Random random = new Random(); // for generating IDs
public void addAlbum(MusicAlbum album) throws IllegalArgumentException {
if (searchAlbum(album.getId()) != null)
throw new IllegalArgumentException("Album ID is not new!");
albums.add(album);
}
public MusicAlbum searchAlbum(String id) {
for (MusicAlbum album : albums) {
if (album.getId().equalsIgnoreCase(id)) {
return album;
}
}
return null;
}
public MusicAlbum removeAlbum(String id) {
MusicAlbum album = searchAlbum(id);
albums.remove(album);
return album;
}
public void updateAlbum(MusicAlbum album)
throws IllegalArgumentException {
if (removeAlbum(album.getId()) == null)
throw new IllegalArgumentException("Album ID does not exist!");
addAlbum(album);
}
public String generateID() {
String formatter = "A%0" + (int)Math.ceil(Math.log10(albums.size() * 2) + 1) + "d";
String ID;
do {
ID = String.format(formatter, random.nextInt(albums.size() * 2 + 1));
} while (searchAlbum(ID) != null);
return ID;
}
public void saveData(String fileName) throws IOException {
// make sure that the file exists or try to create it
File fout = new File(fileName);
if (!fout.exists() && !fout.createNewFile())
return;
PrintWriter out = new PrintWriter(fout);
for (MusicAlbum album: albums) {
out.println(serializeAlbum(album));
}
out.close();
}
public String serializeAlbum(MusicAlbum album) {
return String.format(
"%s;%s;%s;%b;%d",
album.getId(),
album.getName(),
album.getGenre(),
album.isCompilation(),
album.getTrackCount());
}
public void loadFile(String fileName) throws FileNotFoundException {
albums = new ArrayList<>();
Scanner in = new Scanner(new File(fileName));
while (in.hasNext()) {
// --- split the next line with the character ";"
String line = in.nextLine();
String[] tokens = line.split(";");
// --- construct a new MusicAlbum using the resulting tokens. NOTE: This isn't very robust.
// If a line doesn't contain enough data or the data is invalid, this will crash
albums.add(new MusicAlbum(
tokens[0],
tokens[1],
tokens[2],
Boolean.parseBoolean(tokens[3]),
Integer.parseInt(tokens[4])
));
}
}
// ----- these methods need to be implemented
public Object[][] getData() {
// TODO
}
public String[] getColumnNames() {
// TODO
}
}
The sample data being used is in a txt file, formatted as so:
A01;Defiance;Soundtrack;true;24
A02;Insomniac;Punk Rock;false;14
A03;A Great Day For The Race;Gypsy Jazz;false;10
A04;Viva La Internet;Ska;false;31
A05;New Surrender;Rock;false;17
So basically it's this getData() method they want me to implement that is giving me grief. I don't fully understand what they want me to do, nor do I fully understand what the Object[][] does.
I hope I have been clear enough, and I will appreciate all help given. Also please try to explain things as best you can and dumb them down as much as possible, I'm new to a lot of this :)
Thanks for your time.
Object[][] is a 2-dimensional array. Each of its element is an Object[], a one-dimensional array.
Your task is to create a 2 dimensional array, having one element (Object[]) for each of your MusicAlbum. An Object[] should hold the properties of a MusicAlbum like id, name, genre, isCompilation and track_count.
You can create an object array like this:
Object[] arr = new Object[] { "some", "values", 23, true };
You can create a 2 dimensional array like this:
Object[][] arr2d = new Object[size][];
And you can iterate over all your MusicAlbums, create an Object[] for each of them containing the properties of that music album, and set it in the arr2d.
You can set/get elements of a 2-dimensional array just like any other arrays:
// Set first element:
arr2d[0] = arr;
// Get first element:
Object[] firstElement = arr2d[0];
The getColumnNames() method should just return a String[] (a String array) containing the column names, the names of the properties.
And it might be obvious but note that the order you return the column names and the order of the property values (in the elements of the Object[]) should be the same.
I've been stuck at a seemingly simple problem for hours and I just can't find the solution. I'm trying to implement a very simple Forum in Java and I'm trying to load the entrys at the moment.
My forum is a JList that is filled with JPanels and that accepts entries via the JLists DefaultListModel and the addMessage method. So if I add an entry without the database it looks like this:
MessageList m = new MessageList();
m.addMessage("NAME AUTOR", "<html><body style='width: 675px;'>Lorem ipsum dolor sit amet.", "22.01.13", "SOA");
The messageList class looks like this:
public class MessageList extends JList{
DefaultListModel messageModel = new DefaultListModel();
MessageRenderer messageRenderer = new MessageRenderer();
public MessageList( ){
this.setCellRenderer(messageRenderer);
this.setModel(messageModel);
}
public void addMessage(String author, String text, String date, String tag){
messageModel.addElement(new Message(author, text, date, tag));
}
}
I've also written the Code for getting an ArrayList (called allBtr) with the Message Objects (called ConBeitrag) from the database:
ArrayList<ConBeitrag> allBtr = new ArrayList<ConBeitrag>();
ConBeitrag conBtr = new ConBeitrag();
try {
allBtr = conBtr.getAllBtr();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The message objects look like this:
public class ConBeitrag {
private int beitragid;
private int projektid;
private int mitarbeiterid;
private String beitragText;
private String erstellt_am;
private String geaendert_am;
private String schlagwort1;
private String schlagwort2;
private MdBeitrag mdBtr = new MdBeitrag();
public ConBeitrag (){
}
public ConBeitrag(int beitragid, int projektid, int mitarbeiterid, String beitragText, String erstellt_am, String geaendert_am){
this.beitragid = beitragid;
this.projektid = projektid;
this.mitarbeiterid = mitarbeiterid;
this.erstellt_am = erstellt_am;
this.geaendert_am = geaendert_am;
this.beitragText = beitragText;
this.schlagwort1 = schlagwort1;
this.schlagwort2 = schlagwort2;
}
public ArrayList<ConBeitrag> getAllBtr() throws SQLException{
MdBtrInterface modInt;
modInt = new MdBeitrag();
ArrayList<ConBeitrag> AlBtr = modInt.getAllBtr();
for(ConBeitrag object: AlBtr){
System.out.println(object.beitragText);
}
return AlBtr;
}
}
Now what would be the smartest way to get the ArrayList into a form that I can pass into the addMessage method? I've kind of approached this from the GUI end, then from the database end, and now I'm stuck in the middle.
Overwritten toString() method:
#Override
public String toString() {
return mitarbeiterid + beitragstext + erstellt_am + schlagwort1 + schlagwort2;
}
"The messages are stored inside the ArrayList as Objects if that helps. So if I run "System.out.println(allBtr);" it gives me "[ConBeitrag#48f4104f, ConBeitrag#f5ad7f4, ConBeitrag#1517dc0c]"
You need to override the toString method in your ConGeitrag class. Something like this.
public class ConBeitrag {
...
#Override
public String toString(){
return author + ", " + text + ", " + date + ", " + tag;
}
}
You can make the return any format you want. Test this one out and make changes as desired to the format.
Try this out as a Helper method (after you've overridden the toString)
public JList createJList(ResultSet rs){
DefaultListModel model = new DefaultListModel();
while (rs.next()){
String author = rs.getString("author"); // Just an example. You may
String text = rs.getString("text"); // need to retrieve your
String date = rs.getString("date"); // data differently
String tag = rs.getString("tag");
Message message = new Message(author, text, date, tag);
model.addElement(message);
}
JList list = new JList(model);
return list;
}
I don't really see a need for a Custom JList for this situation.
Test run: output : 3testtestnullnull. Besides the formatting, it works fine
public class ConBeitragTest {
public static void main(String[] args) {
ConBeitrag con = new ConBeitrag(1, 2, 3, "test", "test", "test");
System.out.println(con);
}
}
class ConBeitrag {
private int beitragid;
private int projektid;
private int mitarbeiterid;
private String beitragText;
private String erstellt_am;
private String geaendert_am;
private String schlagwort1;
private String schlagwort2;
public ConBeitrag() {
}
public ConBeitrag(int beitragid, int projektid, int mitarbeiterid, String beitragText, String erstellt_am, String geaendert_am) {
this.beitragid = beitragid;
this.projektid = projektid;
this.mitarbeiterid = mitarbeiterid;
this.erstellt_am = erstellt_am;
this.geaendert_am = geaendert_am;
this.beitragText = beitragText;
this.schlagwort1 = schlagwort1; // This is null
this.schlagwort2 = schlagwort2; // This is null
}
#Override
public String toString() {
return mitarbeiterid + beitragText + erstellt_am + schlagwort1 + schlagwort2;
}
}