Copy the list of pojo to clipboard - java
Lang: Java
We are trying to copy the list of pojo to the clipboard in the table format.
Bullet point: what we are trying to achieve here :
1. convert list of pojo into table format
2. If the user copy it in some excel sheet then the it should be copied easily or even if the user try to copy in notepad it should print in the table format.
3. Add some meta data to clipboard to determine the pojo when we will import the table again.
For converting the list of pojo to table format i have used the jtable but i am not able to export all the jtable content to clipboard.
can anyone suggest if i should follow the jtable approach and copy the table to clipboard or any other solution is also available.
Update: as suggested in the comment I tried using the flavours
public class ClipboardTest implements ClipboardOwner {
public static void main(String[] args) {
ClipboardTest clipboardTest = new ClipboardTest();
clipboardTest.copyToClipboard();
//clipboardTest.getFromClipboard();
}
public void copyToClipboard() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Pojo data = new Pojo("1", "2", "ame2", "2", "2");
MyObjectSelection dataSelection = new MyObjectSelection(data);
StringSelection selection = new StringSelection("testing string");
clipboard.setContents(dataSelection, ClipboardTest.this);
System.out.println("copied to clipboard");
}
public void getFromClipboard() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable clipboardContent = clipboard.getContents(this);
DataFlavor[] flavors = clipboardContent.getTransferDataFlavors();
System.out.println("flavors.length = " + flavors.length);
for (int i = 0; i < flavors.length; i++) {
System.out.println("flavor[" + i + "] = " + flavors[i]);
}
}
// ClipboardOwner implementation
#Override
public void lostOwnership(Clipboard clipboard, Transferable transferable) {
System.out.println("ClipboardTest: Lost ownership");
}
}
---
myobjectselection.java
public class MyObjectSelection implements Transferable, ClipboardOwner {
private static DataFlavor dmselFlavor = new DataFlavor(Pojo.class,
"Test data flavor");
private Pojo selection;
public MyObjectSelection(Pojo selection) {
this.selection = selection;
}
// Transferable implementation
#Override
public DataFlavor[] getTransferDataFlavors() {
System.out.println("getTransferDataFlavors");
DataFlavor[] ret = { dmselFlavor };
return ret;
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return dmselFlavor.equals(flavor);
}
#Override
public synchronized Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException {
if (isDataFlavorSupported(flavor)) {
return this.selection;
} else {
throw new UnsupportedFlavorException(dmselFlavor);
}
}
// ClipboardOwner implementation
#Override
public void lostOwnership(Clipboard clipboard, Transferable transferable) {
System.out.println("MyObjectSelection: Lost ownership");
}
}
--
pojo.java
public class Pojo implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private String name1;
private String name2;
private String name3;
private String name4;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
public String getName3() {
return name3;
}
public void setName3(String name3) {
this.name3 = name3;
}
public String getName4() {
return name4;
}
public void setName4(String name4) {
this.name4 = name4;
}
public Pojo(String name, String name1, String name2, String name3,
String name4) {
super();
this.name = name;
this.name1 = name1;
this.name2 = name2;
this.name3 = name3;
this.name4 = name4;
}
}
When i am trying to copy the string value to clipboard it is working but when i am trying to copy the pojo then is it not working.
For every flavor you want to support, you must provide methods to encode the object in the specified format.
This means you'll likely need to provide an encoder for plain text, html and CVS to cover the basics.
So, based on your Pojo, I wrote a Transferable that supports:
List (of Pojos)
HTML
CVS
Plain text
And serialised (as an additional to List, but it's essentially the same)
PojoTransferable
public class PojoTransferable implements Transferable {
public static final DataFlavor POJO_LIST_DATA_FLAVOR = new DataFlavor(List.class, "application/x-java-pojo-list;class=java.util.List");
public static final DataFlavor HTML_DATA_FLAVOR = new DataFlavor("text/html", "HTML");
public static final DataFlavor CSV_DATA_FLAVOR = new DataFlavor("text/csv", "CVS");
public static final DataFlavor PLAIN_DATA_FLAVOR = new DataFlavor("text/plain", "Plain text");
public static final DataFlavor SERIALIZED_DATA_FLAVOR = new DataFlavor(Pojo.class, "application/x-java-serialized-object; Pojo");
private static String[] HEADERS = new String[]{"name", "name1", "name2", "name3", "name4"};
private static Pojo POJO_HEADER = new Pojo("name", "name1", "name2", "name3", "name4");
private List<Pojo> pojos;
public PojoTransferable(List<Pojo> pojos) {
this.pojos = pojos;
}
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{POJO_LIST_DATA_FLAVOR, HTML_DATA_FLAVOR, CSV_DATA_FLAVOR, SERIALIZED_DATA_FLAVOR, PLAIN_DATA_FLAVOR};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
boolean supported = false;
for (DataFlavor mine : getTransferDataFlavors()) {
if (mine.equals(flavor)) {
supported = true;
break;
}
}
return supported;
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object data = null;
if (POJO_LIST_DATA_FLAVOR.equals(flavor)) {
data = pojos;
} else if (HTML_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsHTML().getBytes());
} else if (SERIALIZED_DATA_FLAVOR.equals(flavor)) {
data = pojos;
} else if (CSV_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsCVS().getBytes());
} else if (PLAIN_DATA_FLAVOR.equals(flavor)) {
data = new ByteArrayInputStream(formatAsPlainText().getBytes());
} else {
throw new UnsupportedFlavorException(flavor);
}
return data;
}
protected String formatAsCVS(Pojo pojo) {
StringJoiner sj = new StringJoiner(",");
sj.add(pojo.getName());
sj.add(pojo.getName2());
sj.add(pojo.getName3());
sj.add(pojo.getName4());
return sj.toString();
}
public String formatAsCVS() {
StringBuilder sb = new StringBuilder(128);
sb.append(formatAsCVS(POJO_HEADER));
for (Pojo pojo : pojos) {
sb.append(formatAsCVS(pojo));
}
return "";
}
protected Map<Integer, Integer> columnWidthsFor(Pojo pojo) {
Map<Integer, Integer> columnWidths = new HashMap<>();
columnWidths.put(0, pojo.getName().length());
columnWidths.put(1, pojo.getName1().length());
columnWidths.put(2, pojo.getName2().length());
columnWidths.put(3, pojo.getName3().length());
columnWidths.put(4, pojo.getName4().length());
return columnWidths;
}
protected void apply(Map<Integer, Integer> pojoWidths, Map<Integer, Integer> columnWidths) {
for (int index = 0; index < 5; index++) {
int currentWidth = 2;
if (columnWidths.containsKey(index)) {
currentWidth = columnWidths.get(index);
}
int columnWidth = 2;
if (pojoWidths.containsKey(index)) {
columnWidth = pojoWidths.get(index);
}
columnWidths.put(index, Math.max(currentWidth, columnWidth));
}
}
protected String formatAsPlainText(Pojo pojo, String format) {
return String.format(format, pojo.getName(), pojo.getName1(), pojo.getName2(), pojo.getName3(), pojo.getName4());
}
public static String fill(int padding) {
return String.format("%" + padding + "s", "").replace(" ", "-");
}
public String formatAsPlainText() {
Map<Integer, Integer> columnWidths = new HashMap<>();
apply(columnWidthsFor(POJO_HEADER), columnWidths);
for (Pojo pojo : pojos) {
apply(columnWidthsFor(pojo), columnWidths);
}
StringJoiner sjFormat = new StringJoiner("|");
StringJoiner sjSep = new StringJoiner("+");
for (int index = 0; index < 5; index++) {
int currentWidth = 0;
if (columnWidths.containsKey(index)) {
currentWidth = columnWidths.get(index);
}
sjFormat.add(" %-" + currentWidth + "s ");
sjSep.add(fill(currentWidth + 2));
}
sjFormat.add("%n");
sjSep.add("\n");
String seperator = sjSep.toString();
String format = sjFormat.toString();
StringBuilder sb = new StringBuilder(128);
sb.append(formatAsPlainText(POJO_HEADER, format));
for (Pojo pojo : pojos) {
sb.append(seperator);
sb.append(formatAsPlainText(pojo, format));
}
return sb.toString();
}
public String formatAsHTML() {
StringBuilder sb = new StringBuilder(128);
sb.append("<html><body>");
sb.append("<table border='1'>");
sb.append("<tr>");
for (String header : HEADERS) {
sb.append("<th>").append(header).append("</th>");
}
sb.append("</tr>");
for (Pojo pojo : pojos) {
sb.append("<tr>");
sb.append("<td>").append(pojo.getName()).append("</td>");
sb.append("<td>").append(pojo.getName1()).append("</td>");
sb.append("<td>").append(pojo.getName2()).append("</td>");
sb.append("<td>").append(pojo.getName3()).append("</td>");
sb.append("<td>").append(pojo.getName4()).append("</td>");
sb.append("</tr>");
}
sb.append("</table>");
return sb.toString();
}
}
Test...
Then I wrote a really simple test...
List<Pojo> pojos = new ArrayList<>(25);
pojos.add(new Pojo("one", "two", "three", "four", "five"));
PojoTransferable pt = new PojoTransferable(pojos);
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(pt, new ClipboardOwner() {
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
System.out.println("Lost");
}
});
try {
Object data = cb.getData(PojoTransferable.POJO_LIST_DATA_FLAVOR);
if (data instanceof List) {
List listOfPojos = (List)data;
System.out.println("listOfPojos contains " + listOfPojos.size());
for (Object o : listOfPojos) {
System.out.println(o);
}
}
} catch (UnsupportedFlavorException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
When I run it, it prints out...
listOfPojos contains 1
test.Pojo#5b480cf9
which tells use that the List flavor worked (for our needs), but then I opened up a text edit, Word and Excel and pasted the contents into them...
nb: Excel used the HTML formatting, go figure
Related
How to fix reading/writing value from .dat file
Please find attached Java code. I am unable to fix and execute the code. If I execute Locations.java, no error message is coming, at main(MainAdventure.java:30) at Locations.getLocation(Locations.java:96) If I execute the MainAdventure.java, getting null pointer exception. I tried to debug but no help.Can some one please guide me? MainAdventure.java public class MainAdventure { private static Locations locations = new Locations(); public static void main(String[] args) throws IOException { /* * Change the program to allow players to type full words, or phrases, then move * to the correct location based upon their input. The player should be able to * type commands such as "Go West", "run South", or just "East" and the program * will move to the appropriate location if there is one. As at present, an * attempt to move in an invalid direction should print a message and remain in * the same place. * * Single letter commands (N, W, S, E, Q) should still be available. */ Scanner scanner = new Scanner(System.in); Map<String, String> vocabulary = new HashMap<String, String>(); vocabulary.put("QUIT", "Q"); vocabulary.put("NORTH", "N"); vocabulary.put("SOUTH", "S"); vocabulary.put("WEST", "W"); vocabulary.put("EAST", "E"); Location currentLocation = locations.getLocation(1); while (true) { System.out.println(currentLocation.getDescription()); if (currentLocation.getLocationID() == 0) { break; } Map<String, Integer> exits = currentLocation.getExits(); System.out.print("Available exits are "); for (String exit : exits.keySet()) { System.out.print(exit + ", "); } System.out.println(); String direction = scanner.nextLine().toUpperCase(); if (direction.length() > 1) { String[] words = direction.split(" "); for (String word : words) { if (vocabulary.containsKey(word)) { direction = vocabulary.get(word); break; } } } if (exits.containsKey(direction)) { currentLocation = locations.getLocation(currentLocation.getExits().get(direction)); } else { System.out.println("You cannot go in that direction"); } } locations.close(); } } Locations.java public class Locations implements Map<Integer, Location> { private static Map<Integer, Location> locations = new LinkedHashMap<Integer, Location>(); private static Map<Integer, IndexRecord> index = new LinkedHashMap<>(); private static RandomAccessFile ra; public static void main(String[] args) throws IOException { try (RandomAccessFile rao = new RandomAccessFile("locations_rand.dat", "rwd")) { rao.writeInt(locations.size()); int indexSize = locations.size() * 3 * Integer.BYTES; int locationStart = (int) (indexSize + rao.getFilePointer() + Integer.BYTES); rao.writeInt(locationStart); long indexStart = rao.getFilePointer(); int startPointer = locationStart; rao.seek(startPointer); for (Location location : locations.values()) { rao.writeInt(location.getLocationID()); rao.writeUTF(location.getDescription()); StringBuilder builder = new StringBuilder(); for (String direction : location.getExits().keySet()) { if (!direction.equalsIgnoreCase("Q")) { builder.append(direction); builder.append(","); builder.append(location.getExits().get(direction)); builder.append(","); } } rao.writeUTF(builder.toString()); IndexRecord record = new IndexRecord(startPointer, (int) (rao.getFilePointer() - startPointer)); index.put(location.getLocationID(), record); startPointer = (int) rao.getFilePointer(); } rao.seek(indexStart); for (Integer locationID : index.keySet()) { rao.writeInt(locationID); rao.writeInt(index.get(locationID).getStartByte()); rao.writeInt(index.get(locationID).getLength()); } } } // 1. This first four bytes will contain the number of locations (bytes 0-3) // 2. The next four bytes will contain the start offset of the locations section // (bytes 4-7) // 3. The next section of the file will contain the index (the index is 1692 // bytes long. It will start at byte 8 and end at byte 1699 // 4. The final section of the file will contain the location records (the // data). It will start at byte 1700 static { try { ra = new RandomAccessFile("locations_rand.dat", "rwd"); int numLocations = ra.readInt(); long locationStartPoint = ra.readInt(); while (ra.getFilePointer() < locationStartPoint) { int locationId = ra.readInt(); int locationStart = ra.readInt(); int locationLength = ra.readInt(); IndexRecord record = new IndexRecord(locationStart, locationLength); index.put(locationId, record); } } catch (IOException e) { System.out.println("IOException in static initializer: " + e.getMessage()); } } public Location getLocation(int locationId) throws IOException { IndexRecord record = index.get(locationId); ra.seek(record.getStartByte()); int id = ra.readInt(); String description = ra.readUTF(); String exits = ra.readUTF(); String[] exitPart = exits.split(","); Location location = new Location(locationId, description, null); if (locationId != 0) { for (int i = 0; i < exitPart.length; i++) { System.out.println("exitPart = " + exitPart[i]); System.out.println("exitPart[+1] = " + exitPart[i + 1]); String direction = exitPart[i]; int destination = Integer.parseInt(exitPart[++i]); location.addExit(direction, destination); } } return location; } #Override public int size() { return locations.size(); } #Override public boolean isEmpty() { return locations.isEmpty(); } #Override public boolean containsKey(Object key) { return locations.containsKey(key); } #Override public boolean containsValue(Object value) { return locations.containsValue(value); } #Override public Location get(Object key) { return locations.get(key); } #Override public Location put(Integer key, Location value) { return locations.put(key, value); } #Override public Location remove(Object key) { return locations.remove(key); } #Override public void putAll(Map<? extends Integer, ? extends Location> m) { } #Override public void clear() { locations.clear(); } #Override public Set<Integer> keySet() { return locations.keySet(); } #Override public Collection<Location> values() { return locations.values(); } #Override public Set<Entry<Integer, Location>> entrySet() { return locations.entrySet(); } public void close() throws IOException { ra.close(); } } Location.java public class Location implements Serializable { private final int locationID; private final String description; private final Map<String, Integer> exits; private long serialVersionUID = 1L; public Location(int locationID, String description, Map<String, Integer> exits) { this.locationID = locationID; this.description = description; if (exits != null) { this.exits = new LinkedHashMap<String, Integer>(exits); } else { this.exits = new LinkedHashMap<String, Integer>(); } this.exits.put("Q", 0); } public int getLocationID() { return locationID; } public String getDescription() { return description; } public Map<String, Integer> getExits() { return new LinkedHashMap<String, Integer>(exits); } protected void addExit(String direction, int location) { exits.put(direction, location); } } It looks like that the error I get, is caused by ra.seek(record.getStartByte()); inside Locations class, at the method getLocation(int locationId);. Here is the .dat file.
Make an object of a class from a string in java
I have different classes, each receives strings and convert it to different html formats. Then I have a chooser class where i have switch cases to divert the strings e.g. i send the strings to chooser and stylename like this Chooser chooser = new Chooser(); String text = chooser.format(sometext, stylename); the Chooser class is like this: public String format(String sometext, String stylename) { switch (stylename) { case "NewStyle": NewStyle ns = new NewStyle(); str = ns.refprocess(sometext); break; case "Anotherstyle": Anotherstyle as = new Anotherstyle(); str = as.refprocess(sometext); break; case "Tet_Letters": Turk_J_Chem tet_letters = new Turk_J_Chem(); str = tet_letters.refprocess(sometext); break; } } it there any short way? so that when i send the stylename as String, it converts the to Class, make its object and then send the sometext to that class only?
I assume that you have an interface: static interface Style { String refprocess(String text); } and 3 implemntations: static class NewStyle implements Style { #Override public String refprocess(final String text) { return "new style of " + text; } } static class Anotherstyle implements Style { #Override public String refprocess(final String text) { return "Another style of " + text; } } static class Turk_J_Chem implements Style { #Override public String refprocess(final String text) { return "Turk_J_Chem's style of " + text; } } Then you can create an enum of classes, and format using the enum: enum Styles1 { NEW(NewStyle.class, "NewStyle"), ANOTHER(Anotherstyle.class, "Anotherstyle"), TET_LETTERS(Turk_J_Chem.class, "Tet_Letters"); String str; Class<? extends Style> clazz; Styles1(final Class<? extends Style> clazz, final String str) { this.clazz = clazz; this.str = str; } } static String formatUsingEnum1(final String sometext, final String stylename) { for (final Styles1 style : Styles1.values()) { if (style.str.equals(stylename)) { try { return style.clazz.newInstance().refprocess(sometext); } catch (final Exception e) { break; } } } throw new NotImplementedException(stylename); } Or you can populate the enum with real instances: enum Styles2 { NEW(new NewStyle(), "NewStyle"), ANOTHER(new Anotherstyle(), "Anotherstyle"), TET_LETTERS(new Turk_J_Chem(), "Tet_Letters"); String str; Style style; Styles2(final Style instance, final String str) { style = instance; this.str = str; } } static String formatUsingEnum2(final String sometext, final String stylename) { for (final Styles2 style : Styles2.values()) { if (style.str.equals(stylename)) { try { return style.style.refprocess(sometext); } catch (final Exception e) { break; } } } throw new NotImplementedException(stylename); } But you can insert an abstract function into the enum, with inline implementation for all instances: enum Styles3 { NewStyle() { #Override String refprocess(final String text) { return "new style of " + text; } }, Anotherstyle { #Override String refprocess(final String text) { return "Another style of " + text; } }, TET_LETTERS { #Override String refprocess(final String text) { return "Turk_J_Chem's style of " + text; } }; abstract String refprocess(String text); } static String formatUsingEnum3(final String sometext, final String stylename) { for (final Styles3 style : Styles3.values()) { if (style.name().equalsIgnoreCase(stylename)) { try { return style.refprocess(sometext); } catch (final Exception e) { break; } } } throw new NotImplementedException(stylename); } Enjoy...
Create map of maps from eclipse toString()
Eclipse can auto-generate a toString() method from a object's fields. If those fields are objects then they too may have similarly auto-generated toString() methods. e.g. a President object might look like this: President [country=USA, name=Name [title=Mr, forename=Barack, surname=Obama], address=Address [houseNumber=1600, street=Pennsylvania Avenue, town=Washington]] which is easier to read if I format it: President [ country=USA, name=Name [ title=Mr, forename=Barack, surname=Obama], address=Address [ houseNumber=1600, street=Pennsylvania Avenue, town=Washington]] What is the best way to parse this String to create a map of maps?
I've got a solution, but it's not pretty. I was hoping to be able to avoid the low level String manipulation somehow, but here it is: import java.util.LinkedHashMap; import java.util.Map; public class MappedObject { public String className; public Map<String, String> leafFields = new LinkedHashMap<>(); public Map<String, MappedObject> treeFields = new LinkedHashMap<>(); #Override public String toString() { return "[className=" + className + (leafFields.isEmpty() ? "" : ", leafFields=" + leafFields) + (treeFields.isEmpty() ? "" : ", treeFields=" + treeFields) + "]"; } public static MappedObject createFromString(String s) { MappedObject mo = new MappedObject(); new Mapper(s).mapObject(mo); return mo; } private static class Mapper { private String s; public Mapper(String s) { this.s = s; } private String mapObject(MappedObject mo) { mo.className = removeFirstNCharacters(s.indexOf(' ')); while (s.contains("=")) { removeLeadingNonLetters(); String key = removeFirstNCharacters(s.indexOf('=')); removeFirstNCharacters(1); // remove the = String leafValue = getLeafValue(); if (leafValue != null) { mo.leafFields.put(key, leafValue); if (s.startsWith("]")) { // that was the last field in the tree return s; } } else { MappedObject treeField = new MappedObject(); mo.treeFields.put(key, treeField); s = new Mapper(s).mapObject(treeField); } } return s; // s contains only close brackets - ] } private void removeLeadingNonLetters() { int i = 0; while (!Character.isLetter(s.charAt(i))) { i++; } removeFirstNCharacters(i); } private String removeFirstNCharacters(int n) { String value = s.substring(0, n); s = s.substring(value.length()); return value; } private String getLeafValue() { int endIndex = getEndIndex(); if (!s.contains("[") || s.indexOf('[') > endIndex) { return removeFirstNCharacters(endIndex); } return null; } /** The end of the value, if it's a leaf field. */ private int getEndIndex() { if(s.contains(",")) { return Math.min(s.indexOf(','), s.indexOf(']')); } return s.indexOf(']'); } } }
Java XML parsing error with Jackson
I am trying to convert this xml : <resources> <string name="string_one">one</string> <string name="string_two">two</string> <string name="test2">test2</string> <plurals name="plurals_one"> <item quantity="one">one</item> <item quantity="other">other</item> </plurals> <string name="test1">test1</string> </resources> to something like this: AndroidTextResource{test1, test1} AndroidTextResource{plurals_one#PLURAL#one, one} AndroidTextResource{plurals_one#PLURAL#other, other} AndroidTextResource{string_one, one} AndroidTextResource{string_two, two} The problem is it doesn't parse anything after the "plurals" tag. That is what I get: AndroidTextResource{test1, test1} AndroidTextResource{plurals_one#PLURAL#one, one} AndroidTextResource{plurals_one#PLURAL#other, other} Here is my code: #JacksonXmlRootElement(localName="resources") public class AndroidTextResources { #JsonPropertyOrder({"key", "value"}) public static class MyClass { #JacksonXmlProperty(isAttribute=true, localName="name") public String key; #JacksonXmlText public String value; public AndroidTextResource() { } public AndroidTextResource(final String key, final String value) { this.key = key; this.value = value; } #Override public int hashCode() { return Objects.hashCode( key, value); } #Override public boolean equals(final Object other) { if (other == this) { return true; } if (other == null) { return false; } if (! (other instanceof AndroidTextResource)) { return false; } final AndroidTextResource that = (AndroidTextResource)other; return equal(this.key, that.key) && equal(this.value, that.value) ; } #Override public String toString() { return Objects.toStringHelper(getClass().getSimpleName()) .addValue(key) .addValue(value) .toString(); } } public static class AndroidPlural { public static class AndroidPluralItem { #JacksonXmlProperty(isAttribute=true) public String quantity; #JacksonXmlText public String value; public AndroidPluralItem() {} public AndroidPluralItem(final String quantity, final String value) { this.quantity = quantity; this.value = value; } } #JacksonXmlProperty(isAttribute=true, localName="name") public String key; #JacksonXmlElementWrapper(useWrapping=false) #JacksonXmlProperty(isAttribute=false, localName="item") public List<AndroidPluralItem> items = new ArrayList<MyClass.AndroidPlural.AndroidPluralItem>(); public AndroidPlural() {} public AndroidPlural(final String key) { this.key = key; } public List<AndroidTextResource> toTextResources() { final List<AndroidTextResource> result = new ArrayList<MyClass.AndroidTextResource>(items.size()); for (final AndroidPluralItem item : items) { final AndroidTextResource res = new AndroidTextResource(); res.key = key + "#PLURAL#" + item.quantity; res.value = item.value; result.add(res); } return result; } } #JacksonXmlElementWrapper(useWrapping=false) #JacksonXmlProperty(isAttribute=false, localName="string") public List<AndroidTextResource> textResources = new ArrayList<MyClass.AndroidTextResource>(); #JacksonXmlElementWrapper(useWrapping=false) #JacksonXmlProperty(isAttribute=false, localName="plurals") public List<AndroidPlural> plurals = new ArrayList<MyClass.AndroidPlural>(); } public class AndroidResourceToCsv { public static void main(final String[] args) throws Exception { if (args.length != 2) { System.out .println("You need to specify exactly one input and one output file."); System.exit(-1); } final File inputFile = new File(args[0]); final File outputFile = new File(args[1]); InputStream inputStream = null; try { inputStream = new FileInputStream(inputFile); } finally { inputStream.close(); } final List<AndroidTextResource> allResources = readCsv(inputStream); outputFile.getParentFile().mkdirs(); final CsvMapper csvMapper = new CsvMapper(); final CsvSchema schema = csvMapper.schemaFor(AndroidTextResource.class) .withColumnSeparator(';'); final ObjectWriter writer = csvMapper.writer().withSchema(schema); writer.writeValue(outputFile, allResources); // TODO: parse three times, for string, plural & string array, ignore // other values } public static List<AndroidTextResource> readCsv(final InputStream in) throws JsonParseException, JsonMappingException, IOException { final ObjectMapper xmlMapper = new XmlMapper(); final MyClass = xmlMapper.readValue(in, MyClass.class); final List<AndroidTextResource> allResources = new ArrayList<MyClass.AndroidTextResource>(); allResources.addAll(resources.textResources); for (final AndroidPlural plural : resources.plurals) { allResources.addAll(plural.toTextResources()); } return allResources; } } Does anyone knows what is wrong??Thanks in advance!
How to use Comparator in Java to sort
I learned how to use the comparable but I'm having difficulty with the Comparator. I am having a error in my code: Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable at java.util.Arrays.mergeSort(Unknown Source) at java.util.Arrays.sort(Unknown Source) at java.util.Collections.sort(Unknown Source) at New.TestPeople.main(TestPeople.java:18) Here is my code: import java.util.Comparator; public class People implements Comparator { private int id; private String info; private double price; public People(int newid, String newinfo, double newprice) { setid(newid); setinfo(newinfo); setprice(newprice); } public int getid() { return id; } public void setid(int id) { this.id = id; } public String getinfo() { return info; } public void setinfo(String info) { this.info = info; } public double getprice() { return price; } public void setprice(double price) { this.price = price; } public int compare(Object obj1, Object obj2) { Integer p1 = ((People) obj1).getid(); Integer p2 = ((People) obj2).getid(); if (p1 > p2) { return 1; } else if (p1 < p2){ return -1; } else { return 0; } } } import java.util.ArrayList; import java.util.Collections; public class TestPeople { public static void main(String[] args) { ArrayList peps = new ArrayList(); peps.add(new People(123, "M", 14.25)); peps.add(new People(234, "M", 6.21)); peps.add(new People(362, "F", 9.23)); peps.add(new People(111, "M", 65.99)); peps.add(new People(535, "F", 9.23)); Collections.sort(peps); for (int i = 0; i < peps.size(); i++){ System.out.println(peps.get(i)); } } } I believe it has to do something with the casting in the compare method but I was playing around with it and still could not find the solution
There are a couple of awkward things with your example class: it's called People while it has a price and info (more something for objects, not people); when naming a class as a plural of something, it suggests it is an abstraction of more than one thing. Anyway, here's a demo of how to use a Comparator<T>: public class ComparatorDemo { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Joe", 24), new Person("Pete", 18), new Person("Chris", 21) ); Collections.sort(people, new LexicographicComparator()); System.out.println(people); Collections.sort(people, new AgeComparator()); System.out.println(people); } } class LexicographicComparator implements Comparator<Person> { #Override public int compare(Person a, Person b) { return a.name.compareToIgnoreCase(b.name); } } class AgeComparator implements Comparator<Person> { #Override public int compare(Person a, Person b) { return a.age < b.age ? -1 : a.age == b.age ? 0 : 1; } } class Person { String name; int age; Person(String n, int a) { name = n; age = a; } #Override public String toString() { return String.format("{name=%s, age=%d}", name, age); } } EDIT And an equivalent Java 8 demo would look like this: public class ComparatorDemo { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Joe", 24), new Person("Pete", 18), new Person("Chris", 21) ); Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name)); System.out.println(people); Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1); System.out.println(people); } }
Here's a super short template to do the sorting right away : Collections.sort(people, new Comparator<Person>() { #Override public int compare(final Person lhs, Person rhs) { // TODO return 1 if rhs should be before lhs // return -1 if lhs should be before rhs // return 0 otherwise (meaning the order stays the same) } }); If it's hard to remember, try to just remember that it's similar (in terms of the sign of the number) to: lhs-rhs That's in case you want to sort in ascending order : from smallest number to largest number.
Use People implements Comparable<People> instead; this defines the natural ordering for People. A Comparator<People> can also be defined in addition, but People implements Comparator<People> is not the right way of doing things. The two overloads for Collections.sort are different: <T extends Comparable<? super T>> void sort(List<T> list) Sorts Comparable objects using their natural ordering <T> void sort(List<T> list, Comparator<? super T> c) Sorts whatever using a compatible Comparator You're confusing the two by trying to sort a Comparator (which is again why it doesn't make sense that Person implements Comparator<Person>). Again, to use Collections.sort, you need one of these to be true: The type must be Comparable (use the 1-arg sort) A Comparator for the type must be provided (use the 2-args sort) Related questions When to use Comparable vs Comparator Sorting an ArrayList of Contacts Also, do not use raw types in new code. Raw types are unsafe, and it's provided only for compatibility. That is, instead of this: ArrayList peps = new ArrayList(); // BAD!!! No generic safety! you should've used the typesafe generic declaration like this: List<People> peps = new ArrayList<People>(); // GOOD!!! You will then find that your code doesn't even compile!! That would be a good thing, because there IS something wrong with the code (Person does not implements Comparable<Person>), but because you used raw type, the compiler didn't check for this, and instead you get a ClassCastException at run-time!!! This should convince you to always use typesafe generic types in new code. Always. See also What is a raw type and why shouldn't we use it?
For the sake of completeness, here's a simple one-liner compare method: Collections.sort(people, new Comparator<Person>() { #Override public int compare(Person lhs, Person rhs) { return Integer.signum(lhs.getId() - rhs.getId()); } });
Java 8 added a new way of making Comparators that reduces the amount of code you have to write, Comparator.comparing. Also check out Comparator.reversed Here's a sample import org.junit.Test; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import static org.junit.Assert.assertTrue; public class ComparatorTest { #Test public void test() { List<Person> peopleList = new ArrayList<>(); peopleList.add(new Person("A", 1000)); peopleList.add(new Person("B", 1)); peopleList.add(new Person("C", 50)); peopleList.add(new Person("Z", 500)); //sort by name, ascending peopleList.sort(Comparator.comparing(Person::getName)); assertTrue(peopleList.get(0).getName().equals("A")); assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("Z")); //sort by name, descending peopleList.sort(Comparator.comparing(Person::getName).reversed()); assertTrue(peopleList.get(0).getName().equals("Z")); assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("A")); //sort by age, ascending peopleList.sort(Comparator.comparing(Person::getAge)); assertTrue(peopleList.get(0).getAge() == 1); assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1000); //sort by age, descending peopleList.sort(Comparator.comparing(Person::getAge).reversed()); assertTrue(peopleList.get(0).getAge() == 1000); assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1); } class Person { String name; int age; Person(String n, int a) { name = n; age = a; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } }
For the sake of completeness. Using Java8 people.sort(Comparator.comparingInt(People::getId)); if you want in descending order people.sort(Comparator.comparingInt(People::getId).reversed());
You want to implement Comparable, not Comparator. You need to implement the compareTo method. You're close though. Comparator is a "3rd party" comparison routine. Comparable is that this object can be compared with another. public int compareTo(Object obj1) { People that = (People)obj1; Integer p1 = this.getId(); Integer p2 = that.getid(); if (p1 > p2 ){ return 1; } else if (p1 < p2){ return -1; } else return 0; } Note, you may want to check for nulls in here for getId..just in case.
Two corrections: You have to make an ArrayList of People objects: ArrayList<People> preps = new ArrayList<People>(); After adding the objects to the preps, use: Collections.sort(preps, new CompareId()); Also, add a CompareId class as: class CompareId implements Comparator { public int compare(Object obj1, Object obj2) { People t1 = (People)obj1; People t2 = (People)obj2; if (t1.marks > t2.marks) return 1; else return -1; } }
Here's an example of a Comparator that will work for any zero arg method that returns a Comparable. Does something like this exist in a jdk or library? import java.lang.reflect.Method; import java.util.Comparator; public class NamedMethodComparator implements Comparator<Object> { // // instance variables // private String methodName; private boolean isAsc; // // constructor // public NamedMethodComparator(String methodName, boolean isAsc) { this.methodName = methodName; this.isAsc = isAsc; } /** * Method to compare two objects using the method named in the constructor. */ #Override public int compare(Object obj1, Object obj2) { Comparable comp1 = getValue(obj1, methodName); Comparable comp2 = getValue(obj2, methodName); if (isAsc) { return comp1.compareTo(comp2); } else { return comp2.compareTo(comp1); } } // // implementation // private Comparable getValue(Object obj, String methodName) { Method method = getMethod(obj, methodName); Comparable comp = getValue(obj, method); return comp; } private Method getMethod(Object obj, String methodName) { try { Class[] signature = {}; Method method = obj.getClass().getMethod(methodName, signature); return method; } catch (Exception exp) { throw new RuntimeException(exp); } } private Comparable getValue(Object obj, Method method) { Object[] args = {}; try { Object rtn = method.invoke(obj, args); Comparable comp = (Comparable) rtn; return comp; } catch (Exception exp) { throw new RuntimeException(exp); } } }
public static Comparator<JobSet> JobEndTimeComparator = new Comparator<JobSet>() { public int compare(JobSet j1, JobSet j2) { int cost1 = j1.cost; int cost2 = j2.cost; return cost1-cost2; } };
The solution can be optimized in following way: Firstly, use a private inner class as the scope for the fields is to be the enclosing class TestPeople so as the implementation of class People won't get exposed to outer world. This can be understood in terms of creating an APIthat expects a sorted list of people Secondly, using the Lamba expression(java 8) which reduces the code, hence development effort Hence code would be as below: import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class TestPeople { public static void main(String[] args) { ArrayList<People> peps = new ArrayList<>();// Be specific, to avoid // classCast Exception TestPeople test = new TestPeople(); peps.add(test.new People(123, "M", 14.25)); peps.add(test.new People(234, "M", 6.21)); peps.add(test.new People(362, "F", 9.23)); peps.add(test.new People(111, "M", 65.99)); peps.add(test.new People(535, "F", 9.23)); /* * Collections.sort(peps); * * for (int i = 0; i < peps.size(); i++){ * System.out.println(peps.get(i)); } */ // The above code can be replaced by followin: peps.sort((People p1, People p2) -> p1.getid() - p2.getid()); peps.forEach((p) -> System.out.println(" " + p.toString())); } private class People { private int id; #Override public String toString() { return "People [id=" + id + ", info=" + info + ", price=" + price + "]"; } private String info; private double price; public People(int newid, String newinfo, double newprice) { setid(newid); setinfo(newinfo); setprice(newprice); } public int getid() { return id; } public void setid(int id) { this.id = id; } public String getinfo() { return info; } public void setinfo(String info) { this.info = info; } public double getprice() { return price; } public void setprice(double price) { this.price = price; } } }
Here is a lambda version of comparator. This will sort a string list according to length. Collections.sort(str, (str1, str2) -> { if(str1.length() < str2.length()) return 1; else if(str2.length() < str1.length()) return -1; else return 0; });
You should use the overloaded sort(peps, new People()) method import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Test { public static void main(String[] args) { List<People> peps = new ArrayList<>(); peps.add(new People(123, "M", 14.25)); peps.add(new People(234, "M", 6.21)); peps.add(new People(362, "F", 9.23)); peps.add(new People(111, "M", 65.99)); peps.add(new People(535, "F", 9.23)); Collections.sort(peps, new People().new ComparatorId()); for (int i = 0; i < peps.size(); i++) { System.out.println(peps.get(i)); } } } class People { private int id; private String info; private double price; public People() { } public People(int newid, String newinfo, double newprice) { setid(newid); setinfo(newinfo); setprice(newprice); } public int getid() { return id; } public void setid(int id) { this.id = id; } public String getinfo() { return info; } public void setinfo(String info) { this.info = info; } public double getprice() { return price; } public void setprice(double price) { this.price = price; } class ComparatorId implements Comparator<People> { #Override public int compare(People obj1, People obj2) { Integer p1 = obj1.getid(); Integer p2 = obj2.getid(); if (p1 > p2) { return 1; } else if (p1 < p2){ return -1; } else { return 0; } } } }
Here is my answer for a simple comparator tool public class Comparator { public boolean isComparatorRunning = false; public void compareTableColumns(List<String> tableNames) { if(!isComparatorRunning) { isComparatorRunning = true; try { for (String schTableName : tableNames) { Map<String, String> schemaTableMap = ComparatorUtil.getSchemaTableMap(schTableName); Map<String, ColumnInfo> primaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionOne(), schemaTableMap); Map<String, ColumnInfo> secondaryColMap = ComparatorUtil.getColumnMetadataMap(DbConnectionRepository.getConnectionTwo(), schemaTableMap); ComparatorUtil.publishColumnInfoOutput("Comparing table : "+ schemaTableMap.get(CompConstants.TABLE_NAME)); compareColumns(primaryColMap, secondaryColMap); } } catch (Exception e) { ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage()); } isComparatorRunning = false; } } public void compareColumns(Map<String, ColumnInfo> primaryColMap, Map<String, ColumnInfo> secondaryColMap) { try { boolean isEqual = true; for(Map.Entry<String, ColumnInfo> entry : primaryColMap.entrySet()) { String columnName = entry.getKey(); ColumnInfo primaryColInfo = entry.getValue(); ColumnInfo secondaryColInfo = secondaryColMap.remove(columnName); if(secondaryColInfo == null) { // column is not present in Secondary Environment ComparatorUtil.publishColumnInfoOutput("ALTER", primaryColInfo); isEqual = false; continue; } if(!primaryColInfo.equals(secondaryColInfo)) { isEqual = false; // Column not equal in secondary env ComparatorUtil.publishColumnInfoOutput("MODIFY", primaryColInfo); } } if(!secondaryColMap.isEmpty()) { isEqual = false; for(Map.Entry<String, ColumnInfo> entry : secondaryColMap.entrySet()) { // column is not present in Primary Environment ComparatorUtil.publishColumnInfoOutput("DROP", entry.getValue()); } } if(isEqual) { ComparatorUtil.publishColumnInfoOutput("--Exact Match"); } } catch (Exception e) { ComparatorUtil.publishColumnInfoOutput("ERROR"+e.getMessage()); } } public void compareTableColumnsValues(String primaryTableName, String primaryColumnNames, String primaryCondition, String primaryKeyColumn, String secTableName, String secColumnNames, String secCondition, String secKeyColumn) { if(!isComparatorRunning) { isComparatorRunning = true; Connection conn1 = DbConnectionRepository.getConnectionOne(); Connection conn2 = DbConnectionRepository.getConnectionTwo(); String query1 = buildQuery(primaryTableName, primaryColumnNames, primaryCondition, primaryKeyColumn); String query2 = buildQuery(secTableName, secColumnNames, secCondition, secKeyColumn); try { Map<String,Map<String, Object>> query1Data = executeAndRefactorData(conn1, query1, primaryKeyColumn); Map<String,Map<String, Object>> query2Data = executeAndRefactorData(conn2, query2, secKeyColumn); for(Map.Entry<String,Map<String, Object>> entry : query1Data.entrySet()) { String key = entry.getKey(); Map<String, Object> value = entry.getValue(); Map<String, Object> secondaryValue = query2Data.remove(key); if(secondaryValue == null) { ComparatorUtil.publishColumnValuesInfoOutput("NO SUCH VALUE AVAILABLE IN SECONDARY DB "+ value.toString()); continue; } compareMap(value, secondaryValue, key); } if(!query2Data.isEmpty()) { ComparatorUtil.publishColumnValuesInfoOutput("Extra Values in Secondary table "+ ((Map)query2Data.values()).values().toString()); } } catch (Exception e) { ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage()); } isComparatorRunning = false; } } private void compareMap(Map<String, Object> primaryValues, Map<String, Object> secondaryValues, String columnIdentification) { for(Map.Entry<String, Object> entry : primaryValues.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); Object secValue = secondaryValues.get(key); if(value!=null && secValue!=null && !String.valueOf(value).equalsIgnoreCase(String.valueOf(secValue))) { ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Secondary Table does not match value ("+ value +") for column ("+ key+")"); } if(value==null && secValue!=null) { ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in primary table for column "+ key); } if(value!=null && secValue==null) { ComparatorUtil.publishColumnValuesInfoOutput(columnIdentification+" : Values not available in Secondary table for column "+ key); } } } private String buildQuery(String tableName, String column, String condition, String keyCol) { if(!"*".equalsIgnoreCase(column)) { String[] keyColArr = keyCol.split(","); for(String key: keyColArr) { if(!column.contains(key.trim())) { column+=","+key.trim(); } } } StringBuilder queryBuilder = new StringBuilder(); queryBuilder.append("select "+column+" from "+ tableName); if(!ComparatorUtil.isNullorEmpty(condition)) { queryBuilder.append(" where 1=1 and "+condition); } return queryBuilder.toString(); } private Map<String,Map<String, Object>> executeAndRefactorData(Connection connection, String query, String keyColumn) { Map<String,Map<String, Object>> result = new HashMap<String, Map<String,Object>>(); try { PreparedStatement preparedStatement = connection.prepareStatement(query); ResultSet resultSet = preparedStatement.executeQuery(); resultSet.setFetchSize(1000); if (resultSet != null && !resultSet.isClosed()) { while (resultSet.next()) { Map<String, Object> columnValueDetails = new HashMap<String, Object>(); int columnCount = resultSet.getMetaData().getColumnCount(); for (int i=1; i<=columnCount; i++) { String columnName = String.valueOf(resultSet.getMetaData().getColumnName(i)); Object columnValue = resultSet.getObject(columnName); columnValueDetails.put(columnName, columnValue); } String[] keys = keyColumn.split(","); String newKey = ""; for(int j=0; j<keys.length; j++) { newKey += String.valueOf(columnValueDetails.get(keys[j])); } result.put(newKey , columnValueDetails); } } } catch (SQLException e) { ComparatorUtil.publishColumnValuesInfoOutput("ERROR"+e.getMessage()); } return result; } } Utility Tool for the same public class ComparatorUtil { public static Map<String, String> getSchemaTableMap(String tableNameWithSchema) { if(isNullorEmpty(tableNameWithSchema)) { return null; } Map<String, String> result = new LinkedHashMap<>(); int index = tableNameWithSchema.indexOf("."); String schemaName = tableNameWithSchema.substring(0, index); String tableName = tableNameWithSchema.substring(index+1); result.put(CompConstants.SCHEMA_NAME, schemaName); result.put(CompConstants.TABLE_NAME, tableName); return result; } public static Map<String, ColumnInfo> getColumnMetadataMap(Connection conn, Map<String, String> schemaTableMap) { try { String schemaName = schemaTableMap.get(CompConstants.SCHEMA_NAME); String tableName = schemaTableMap.get(CompConstants.TABLE_NAME); ResultSet resultSetConnOne = conn.getMetaData().getColumns(null, schemaName, tableName, null); Map<String, ColumnInfo> resultSetTwoColInfo = getColumnInfo(schemaName, tableName, resultSetConnOne); return resultSetTwoColInfo; } catch (SQLException e) { e.printStackTrace(); } return null; } /* Number Type mapping * 12-----VARCHAR * 3-----DECIMAL * 93-----TIMESTAMP * 1111-----OTHER */ public static Map<String, ColumnInfo> getColumnInfo(String schemaName, String tableName, ResultSet columns) { try { Map<String, ColumnInfo> tableColumnInfo = new LinkedHashMap<String, ColumnInfo>(); while (columns.next()) { ColumnInfo columnInfo = new ColumnInfo(); columnInfo.setSchemaName(schemaName); columnInfo.setTableName(tableName); columnInfo.setColumnName(columns.getString("COLUMN_NAME")); columnInfo.setDatatype(columns.getString("DATA_TYPE")); columnInfo.setColumnsize(columns.getString("COLUMN_SIZE")); columnInfo.setDecimaldigits(columns.getString("DECIMAL_DIGITS")); columnInfo.setIsNullable(columns.getString("IS_NULLABLE")); tableColumnInfo.put(columnInfo.getColumnName(), columnInfo); } return tableColumnInfo; } catch (Exception e) { e.printStackTrace(); } return null; } public static boolean isNullOrEmpty(Object obj) { if (obj == null) return true; if (String.valueOf(obj).equalsIgnoreCase("NULL")) return true; if (obj.toString().trim().length() == 0) return true; return false; } public static boolean isNullorEmpty(String str) { if(str == null) return true; if(str.trim().length() == 0) return true; return false; } public static void publishColumnInfoOutput(String type, ColumnInfo columnInfo) { String str = "ALTER TABLE "+columnInfo.getSchemaName()+"."+columnInfo.getTableName(); switch(type.toUpperCase()) { case "ALTER": if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) { str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");"; } else { str += " ADD ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));"; } break; case "DROP": str += " DROP ("+columnInfo.getColumnName()+");"; break; case "MODIFY": if("NUMBER".equalsIgnoreCase(columnInfo.getDatatype()) || "DATE".equalsIgnoreCase(columnInfo.getDatatype())) { str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype()+");"; } else { str += " MODIFY ("+columnInfo.getColumnName()+" "+ columnInfo.getDatatype() +"("+columnInfo.getColumnsize()+"));"; } break; } publishColumnInfoOutput(str); } public static Map<Integer, String> allJdbcTypeName = null; public static Map<Integer, String> getAllJdbcTypeNames() { Map<Integer, String> result = new HashMap<Integer, String>(); if(allJdbcTypeName != null) return allJdbcTypeName; try { for (Field field : java.sql.Types.class.getFields()) { result.put((Integer) field.get(null), field.getName()); } } catch (Exception e) { e.printStackTrace(); } return allJdbcTypeName=result; } public static String getStringPlaces(String[] attribs) { String params = ""; for(int i=0; i<attribs.length; i++) { params += "?,"; } return params.substring(0, params.length()-1); } } Column Info Class public class ColumnInfo { private String schemaName; private String tableName; private String columnName; private String datatype; private String columnsize; private String decimaldigits; private String isNullable;
If you are using Java 8 then it's better to use below code like this: Comparator<People> comparator = Comparator.comparing(People::getName); And then simply use: Collections.sort(list, comparator); If you are using Java 7 or below then you can use a comparator for customized sorting order by implementing compare method. For example: import java.util.Comparator; public class PeopleNameComparator implements Comparator<People> { #Override public int compare(People people1, People people2) { return people1.getName().compareTo(people2.getName()); } } And then simply use like this: Collections.sort(list, new PeopleNameComparator);
Do not waste time implementing Sorting Algorithm by your own. Instead use Collections.sort() to sort data.