Common data structures in Java
1. Array
1.1 representations and definitions:
int[] a;/*statement*/ int[5] a;/*error*/ int[ ] a = new int[100];/*definition*/
- Array length definition is not required to be constant
- You do not need to add a specific value when declaring a variable. It is only specified when new
1.2 initialization:
- Numeric array initialization: all elements are 0.
- boolean array initialization: all elements are false.
- String array initialization: all strings are null.
- Once you create an array, you can no longer change its size. If it is changed in the operation, the dynamic array -- array list is used
1.2.1 initialization mode
Brackets {}
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 }; smallPrimes = new int[] { 17, 19, 23, 29, 31, 37}; //Initialize one by one int[] c = new int[2]; //c has 2 elements, both of which are 0 c[0] = 10; c[1] = 20; //Initialize one by one int[] anonymous = { 17, 19, 23, 29, 31, 37 }; smallPrimes = anonymous;
1.3 array copy
Address copy: two variables will reference the same array
int[] luckyNumbers = smallPrimes; 1uckyNumbers[5] = 12; /* now smallPrimes[5] is also 12 */
Numerical copy: copyOf method of Arrays class
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
- If the array elements are numeric, the extra elements will be assigned 0
- If the array element is Boolean, it is assigned false.
- Conversely, if the length is less than the length of the original array, only the first data element is copied.
1.6 array traversal
//You need to control the index position yourself for(int i=0;i<d.length;i++) { System.out.println(d[i]); } //No need to control index position for(int e : d) { System.out.println(e); }
1.5 multidimensional array
Multidimensional array: that is, array elements are also arrays
Irregular array: each row of the array has a different length.
1 1 1 1 2 1 1 3 3 1 int[][] odds = new int[NMAX + 1 ][]; for (int n = 0; n <= NMAX; n++) odds[n] = new int[n + 1];
2. JCF: Java Collection Framework
2.1 JCF overview
JCF (Java container framework): a standard architecture for representing and manipulating containers
- External interface: the abstract data type that can be stored in the container
- Implementation of interface: reusable data structure
- Algorithm: search and sort data
The Collection interface of JCF is Collection
- add,contains,remove,size
- iterator
Iterator interface of JCF
- hasNext
- next
- remove
Main data structure implementation classes of JCF
- List (List, ArrayList, LinkedList)
- Set (Set, HashSet, TreeSet, LinkedHashSet)
- Mapping (Map, HashMap, TreeMap, LinkedHashMap)
Main algorithm classes of JCF
- Arrays: find and sort arrays
- Collection s: sort and find Collections and their subclasses
- Green is a List, yellow is a Set, and blue is a map
2.2 Collection interface
: in the Java class library, a Collection has two basic interfaces: Collection and Map
2.3 iterators
: an iterator is a data type that checks the elements in a container and traverses the elements.
The Iterator interface contains four methods:
public interface Iterator<E> { E next(); //Points to the next iterator and returns the previous element boolean hasNext(); void remove();//Element value before deleting iterator default void forEachRemaining(Consumer<? super E> action); } Traversal: 1. Collection<String> c = . . .; Iterator<String> iter = c.iterator(); while (iter.hasNext()) { String element = iter.next(); dosomethingwith element; } 2. for (String element : c) { dosomethingwith element; } 3.stay Java SE 8 You don't even have to write a loop. Can call forEachRemaining Method and provide a lambda Expression (which processes an element). This is called for each element of the iterator lambda Expression until there are no more elements. iterator.forEachRemaining(element -> dosomethingwith element); delete : remove Not called before next Will be illegal If you want to delete two adjacent elements, you cannot directly call: it.remove(); it.remove();// Error Must be called first next Cross over the element to be deleted. it,remove(); it.next(); it.remove(); // OK
3. List
List: List
- Ordered Collection
- Allow duplicate elements
- {1,2,4,{5,2},1,3}
List main implementation
- ArrayList (asynchronous)
- LinkedList (asynchronous)
- Vector (synchronous)
3.1 ArrayList
ArrayList features:
- Lists implemented as arrays do not support synchronization
• List list = Collections.synchronizedList(new ArrayList(…)); (synchronize) - Using the index location, you can quickly locate access
- Insert and delete operations that are not suitable for the specified location
- It is suitable for data with little change and is mainly used for query
- Compared with Java arrays, its capacity is dynamically adjustable. ArrayList automatically expands the container size by 50% when the element fills the container
Addition, deletion and traversal of ArrayList:
import java.util.ArrayList; import java.util.Iterator; //Vector is almost the same as ArrayList, except that vector itself is synchronized public class ArrayListTest { public static void main(String[] a) { ArrayList<Integer> al = new ArrayList<Integer>(); al.add(3); al.add(2); al.add(1); al.add(4); al.add(5); al.add(6); al.add(new Integer(6)); System.out.print("The third element is "); System.out.println(al.get(3)); al.remove(3); //Delete the fourth element and move the following element forward al.add(3, 9); //Insert 9 into the fourth element and move the following element back System.out.println("======traversal method ============="); ArrayList<Integer> as = new ArrayList<Integer>(100000); for (int i=0; i<100000; i++) { as.add(i); } traverseByIterator(as); traverseByIndex(as); traverseByFor(as); } public static void traverseByIterator(ArrayList<Integer> al) { long startTime = System.nanoTime(); System.out.println("============Iterator traversal=============="); Iterator<Integer> iter1 = al.iterator(); while(iter1.hasNext()){ iter1.next(); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } public static void traverseByIndex(ArrayList<Integer> al) { long startTime = System.nanoTime(); System.out.println("============Random index value traversal=============="); for(int i=0;i<al.size();i++) { al.get(i); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } public static void traverseByFor(ArrayList<Integer> al) { long startTime = System.nanoTime(); System.out.println("============for Loop traversal=============="); for(Integer item : al) { ; } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } }
3.2 LinkedList:
LinkedList features:
- The list implemented by two-way linked list does not support synchronization
• List list = Collections.synchronizedList(new LinkedList(...)); - Sequential access is efficient, random access is poor, and intermediate insertion and deletion are efficient
- It can be operated as stack, queue and double ended queue
- Applicable to frequently changing data
Adding, deleting and traversing LinkedList:
Code and ArrayList be similar
3.3 Vector
- Similar to ArrayList
- Vector is used for synchronization
4. Set
Set set
- Certainty: any object can be determined whether it belongs to a set
- Dissimilarity: each element in the set is not different. Note that the content is different and is not repeated
- Disorder: order independent within a set
Set interface in Java
- HashSet (collection based on hash function, unordered, does not support synchronization)
- Linkedhashset (a set based on hash function and two-way linked list, which is inserted in order and not
Support synchronization) - TreeSet (a collection based on tree structure, the contents can be sorted, and synchronization is not supported)
4.1 HashSet
Based on HashMap, it can accommodate null elements and does not support synchronization
Set s = Collections.synchronizedSet(new HashSet(...));
- add adds an element
- clear clears the entire HashSet
- contains determines whether an element is included
- remove deletes an element size
- retainAll calculates the intersection of two sets
Addition, deletion and traversal of HashSet:
import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; public class HashSetTest { public static void main(String[] args) { HashSet<Integer> hs = new HashSet<Integer>(); hs.add(null); hs.add(1000); hs.add(20); hs.add(3); hs.add(40000); hs.add(5000000); hs.add(3); //3 repeat hs.add(null); //null duplicate System.out.println(hs.size()); //6 if(!hs.contains(6)) { hs.add(6); } System.out.println(hs.size()); //7 hs.remove(20); System.out.println(hs.size()); //6 //hs.clear(); //System.out.println(hs.size()); //0 System.out.println("============for Loop traversal=============="); for(Integer item : hs) { System.out.println(item); } System.out.println("============Test set intersection=============="); HashSet<String> set1 = new HashSet<String>(); HashSet<String> set2 = new HashSet<String>(); set1.add("a"); set1.add("b"); set1.add("c"); set2.add("c"); set2.add("d"); set2.add("e"); //intersection set1.retainAll(set2); System.out.println("Intersection is "+set1); System.out.println("============Test the speed of multiple traversal methods=============="); HashSet<Integer> hs2 = new HashSet<Integer>(); for(int i=0;i<100000;i++) { hs2.add(i); } traverseByIterator(hs2); traverseByFor(hs2); } public static void traverseByIterator(HashSet<Integer> hs) { long startTime = System.nanoTime(); System.out.println("============Iterator traversal=============="); Iterator<Integer> iter1 = hs.iterator(); while(iter1.hasNext()){ iter1.next(); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } public static void traverseByFor(HashSet<Integer> hs) { long startTime = System.nanoTime(); System.out.println("============for Loop traversal=============="); for(Integer item : hs) { ; } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } }
4.2 LinkedHashSet
- Inheriting HashSet, which is also implemented based on HashMap and can accommodate null elements
- Maintain the insertion order through a two-way linked list
- Synchronization is not supported
• Set s = Collections.synchronizedSet(new LinkedHashSet(...)); - The method is basically the same as HashSet
• add, clear, contains, remove, size
Additions, deletions and iterations of LinkedHashSet:
And HashSet be similar
4.3 TreeSet
- Implemented based on TreeMap, it can not accommodate null elements and does not support synchronization
• SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...)); - Sort by compareTo method or specify Comparator (content sort)
- add adds an element
- clear clears the entire TreeSet
- contains determines whether an element is included
- remove deletes an element size
Addition, deletion and iteration of TreeSet:
import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.TreeSet; public class TreeSetTest { public static void main(String[] args) { TreeSet<Integer> ts = new TreeSet<Integer>(); // ts.add(null); Error, null is not supported ts.add(1000); ts.add(20); ts.add(3); ts.add(40000); ts.add(5000000); ts.add(3); //3 repeat System.out.println(ts.size()); //5 if(!ts.contains(6)) { ts.add(6); } System.out.println(ts.size()); //6 ts.remove(4); System.out.println(ts.size()); //6 //lhs.clear(); //System.out.println(lhs.size()); //0 System.out.println("============for Loop traversal=============="); for(Integer item : ts) { System.out.println(item); } TreeSet<Integer> ts2 = new TreeSet<Integer>(); for(int i=0;i<100000;i++) { ts2.add(i); } traverseByIterator(ts2); traverseByFor(ts2); } public static void traverseByIterator(TreeSet<Integer> hs) { long startTime = System.nanoTime(); System.out.println("============Iterator traversal=============="); Iterator<Integer> iter1 = hs.iterator(); while(iter1.hasNext()){ iter1.next(); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } public static void traverseByFor(TreeSet<Integer> hs) { long startTime = System.nanoTime(); System.out.println("============for Loop traversal=============="); for(Integer item : hs) { ; } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } }
4.4 principle of repetition and size of judgment object
The elements of HashSet, linkedhashset and TreeSet can only be objects
HashSet and LinkedHashSet determine the principle of element repetition (according to hashcode and equals)
- Determine whether the hashCode return values of the two elements are the same. If they are different, return false
- If the two hashcodes are the same, judge the equals method. If they are different, return false; Otherwise, return true.
– hashCode and equals methods are available to all classes, because the Object class has
TreeSet determines the principle of element repetition
- The element needs to inherit from the Comparable interface and override the compareTo method of the two elements
Code reference:
Cat class (hashcode, equals not overridden)
Dog class (override hashcode, equals)
class Cat { private int size; public Cat(int size) { this.size = size; } } class Dog { private int size; public Dog(int s) { size = s; } public int getSize() { return size; } public boolean equals(Object obj2) { System.out.println("Dog equals()~~~~~~~~~~~"); if(0==size - ((Dog) obj2).getSize()) { return true; } else { return false; } } public int hashCode() { System.out.println("Dog hashCode()~~~~~~~~~~~"); return size; } public String toString() { System.out.print("Dog toString()~~~~~~~~~~~"); return size + ""; } } public class Tiger implements Comparable{ private int size; public Tiger(int s) { size = s; } public int getSize() { return size; } public int compareTo(Object o) { System.out.println("Tiger compareTo()~~~~~~~~~~~"); return size - ((Tiger) o).getSize(); } }
Ascending order: if obj1-obj2 > 0, 1 is returned, indicating that it is sorted from small to large
Descending order: if obj1-obj2 > 0, - 1 is returned, indicating that it is sorted from large to small
Cat, Dog, Tiger test:
import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.TreeSet; public class ObjectHashSetTest { public static void main(String[] args) { System.out.println("==========Cat HashSet =============="); HashSet<Cat> hs = new HashSet<Cat>(); hs.add(new Cat(2)); hs.add(new Cat(1)); hs.add(new Cat(3)); hs.add(new Cat(5)); hs.add(new Cat(4)); hs.add(new Cat(4)); System.out.println(hs.size()); //6 System.out.println("==========Dog HashSet =============="); HashSet<Dog> hs2 = new HashSet<Dog>(); hs2.add(new Dog(2)); hs2.add(new Dog(1)); hs2.add(new Dog(3)); hs2.add(new Dog(5)); hs2.add(new Dog(4)); hs2.add(new Dog(4)); System.out.println(hs2.size()); //5 System.out.println("==========Tiger HashSet =============="); HashSet<Tiger> hs3 = new HashSet<Tiger>(); hs3.add(new Tiger(2)); hs3.add(new Tiger(1)); hs3.add(new Tiger(3)); hs3.add(new Tiger(5)); hs3.add(new Tiger(4)); hs3.add(new Tiger(4)); System.out.println(hs3.size()); //6 } }
Cat does not overwrite hashcode and equals, and cannot judge the same in HashSet
Dog has overwritten hashcode and equals, and can judge the same in HashSet
Tiger does not override hashcode and equals, so it cannot judge the same in HashSet, but it overrides the compareTo method in Comparable interface, so it can judge the same in TreeSet.
import java.util.TreeSet; public class ObjectTreeSetTest { public static void main(String[] args) { System.out.println("==========Tiger TreeSet =============="); TreeSet<Tiger> ts3 = new TreeSet<Tiger>(); ts3.add(new Tiger(2)); ts3.add(new Tiger(1)); ts3.add(new Tiger(3)); ts3.add(new Tiger(5)); ts3.add(new Tiger(4)); ts3.add(new Tiger(4)); System.out.println(ts3.size()); //5 } }
5. Map
Map mapping
- Mathematical definition: the element correspondence between two sets.
- One input corresponds to one output
- {1, Zhang San}, {2, Li Si}, {Key, Value}, Key Value pair, K-V pair
Map in Java
- Hashtable (synchronous, slow, small amount of data)
- HashMap (does not support synchronization, fast and large amount of data)
- Properties (synchronization, file form, small amount of data)
5.1 Hashtable
- K-V pair, neither K nor V is allowed to be null
- Synchronization, multithreading safety
- Disordered
- Suitable for small amount of data
– main methods: clear, contains/containsValue, containsKey, get,
put,remove, size
Addition, deletion and traversal of HashTable:
import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class HashtableTest { public static void main(String[] args) { Hashtable<Integer,String> ht =new Hashtable<Integer,String>(); //ht.put(1, null); Compile without error and run with error //ht.put(null,1); Compilation error ht.put(1000, "aaa"); ht.put(2, "bbb"); ht.put(30000, "ccc"); System.out.println(ht.contains("aaa")); System.out.println(ht.containsValue("aaa")); System.out.println(ht.containsKey(30000)); System.out.println(ht.get(30000)); ht.put(30000, "ddd"); //Update override ccc System.out.println(ht.get(30000)); ht.remove(2); System.out.println("size: " + ht.size()); ht.clear(); System.out.println("size: " + ht.size()); Hashtable<Integer,String> ht2 =new Hashtable<Integer,String>(); for(int i=0;i<100000;i++) { ht2.put(i, "aaa"); } traverseByEntry(ht2); traverseByKeySet(ht2); traverseByKeyEnumeration(ht2); } public static void traverseByEntry(Hashtable<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============Entry Iterator traversal=============="); Integer key; String value; Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator(); while(iter.hasNext()) { Map.Entry<Integer, String> entry = iter.next(); // Get key key = entry.getKey(); // Get value value = entry.getValue(); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } public static void traverseByKeySet(Hashtable<Integer,String> ht) { long startTime = System.nanoTime(); System.out.println("============KeySet Iterator traversal=============="); Integer key; String value; Iterator<Integer> iter = ht.keySet().iterator(); while(iter.hasNext()) { key = iter.next(); // Get value value = ht.get(key); //System.out.println("Key:" + key + ", Value:" + value); } long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println(duration + "nanosecond"); } }
5.2 HashMap
- For K-V pairs, both K and V are allowed to be null
- Out of sync, multithreading is unsafe
• Map m = Collections.synchronizedMap(new HashMap(...)); - Disordered
– main methods: clear, containsValue, containsKey, get, put,remove, size
Addition, deletion and traversal of HashMap:
And HashTable be similar
5.3 LinkedHashMap
HashMap maintaining insertion order based on bidirectional linked list
And HashTable be similar
5.4 TreeMap
The Map based on red black tree can be sorted and output according to the natural sorting of key or compareTo method
And HashTable be similar
5.5 • Properties
- Inherited from Hashtable
- You can save K-V pairs in a file
- It is suitable for configuration files with small amount of data
– methods inherited from Hashtable: clear, contains/containsValue, containsKey,
get, put,remove, size
– the load method loaded from the file and the store method written to the file
– get the property getProperty and set the property setProperty
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Properties; //Common operations of the Properties class public class PropertiesTest { //Read Value according to Key public static String GetValueByKey(String filePath, String key) { Properties pps = new Properties(); try { InputStream in = new BufferedInputStream (new FileInputStream(filePath)); pps.load(in); //All K-V pairs are loaded String value = pps.getProperty(key); //System.out.println(key + " = " + value); return value; }catch (IOException e) { e.printStackTrace(); return null; } } //Read all information of Properties public static void GetAllProperties(String filePath) throws IOException { Properties pps = new Properties(); InputStream in = new BufferedInputStream(new FileInputStream(filePath)); pps.load(in); //All K-V pairs are loaded Enumeration en = pps.propertyNames(); //Get the name of the configuration file while(en.hasMoreElements()) { String strKey = (String) en.nextElement(); String strValue = pps.getProperty(strKey); //System.out.println(strKey + "=" + strValue); } } //Write Properties information public static void WriteProperties (String filePath, String pKey, String pValue) throws IOException { File file = new File(filePath); if(!file.exists()) { file.createNewFile(); } Properties pps = new Properties(); InputStream in = new FileInputStream(filePath); //Read the attribute list (key and element pairs) from the input stream pps.load(in); //Call the put method of Hashtable. Use the getProperty method to provide parallelism. //Enforce strings for keys and values of properties. The return value is the result of the Hashtable call put. OutputStream out = new FileOutputStream(filePath); pps.setProperty(pKey, pValue); //In a format suitable for loading into the Properties table using the load method, //Write the list of Properties (key and element pairs) in this Properties table to the output stream pps.store(out, "Update " + pKey + " name"); out.close(); } public static void main(String [] args) throws IOException{ System.out.println("write in Test.properties================"); WriteProperties("Test.properties","name", "12345"); System.out.println("load Test.properties================"); GetAllProperties("Test.properties"); System.out.println("from Test.properties load================"); String value = GetValueByKey("Test.properties", "name"); System.out.println("name is " + value); } }
6. Tools
Tool classes in JCF
: do not store data, but on the data container to achieve efficient operation
- sort
- search
– Arrays class
– Collections class
6.1 Arrays: the processing object is an array
- Sort: sort the array, sort/parallelSort.
- Find: find an element from the array, binarySearch.
– binary search needs to be sorted in advance - Batch copy: batch copy elements from the source array to the target array, copyOf.
- Batch assignment: batch assignment of arrays, fill.
- Equivalence comparison: determine whether the contents of two arrays are the same, equals.
import java.util.Arrays; import java.util.Random; public class ArraysTest { public static void main(String[] args) { testSort(); testSearch(); testCopy(); testFill(); testEquality(); } public static void testSort() { Random r = new Random(); int[] a = new int[10]; for(int i=0;i<a.length;i++) { a[i] = r.nextInt(); } System.out.println("===============Test sequencing================"); System.out.println("Before sorting"); for(int i=0;i<a.length;i++) { System.out.print(a[i] + ","); } System.out.println(); System.out.println("After sorting"); Arrays.sort(a); for(int i=0;i<a.length;i++) { System.out.print(a[i] + ","); } System.out.println(); } public static void testSearch() { Random r = new Random(); int[] a = new int[10]; for(int i=0;i<a.length;i++) { a[i] = r.nextInt(); } a[a.length-1] = 10000; System.out.println("===========Test lookup============"); System.out.println("10000 The location is" + Arrays.binarySearch(a, 10000)); } public static void testCopy() { Random r = new Random(); int[] a = new int[10]; for(int i=0;i<a.length;i++) { a[i] = r.nextInt(); } int[] b = Arrays.copyOf(a, 5); System.out.println("===========Test the first five elements of the copy============"); System.out.print("Source array:"); for(int i=0;i<a.length;i++) { System.out.print(a[i] + ","); } System.out.println(); System.out.print("Target array:"); for(int i=0;i<b.length;i++) { System.out.print(b[i] + ","); } System.out.println(); } public static void testFill() { int[] a = new int[10]; Arrays.fill(a, 100); Arrays.fill(a, 2, 8, 200); System.out.println("===========Test batch assignment============"); System.out.print("After array assignment:"); for(int i=0;i<a.length;i++) { System.out.print(a[i] + ","); } System.out.println(); } public static void testEquality() { int[] a = new int[10]; Arrays.fill(a, 100); int[] b = new int[10]; Arrays.fill(b, 100); System.out.println(Arrays.equals(a, b)); b[9] = 200; System.out.println(Arrays.equals(a, b)); } }
6.2 Collections: the processing object is Collection and its subclasses
- Sort: sort the List, sort.
- Search: search for elements from the List, binarySearch
- Batch assignment: batch assignment to List, fill.
- max, Min: find the maximum / minimum value in the set, max, min
- Reverse order: reverse the List
public class CollectionsTest { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(12); list.add(2); list.add(19); // sort Collections.sort(list); // retrieval System.out.println("The index value of the element is:" + Collections.binarySearch(list, 12)); //Max min System.out.println("Maximum:" + Collections.max(list)); System.out.println("Minimum:" + Collections.min(list)); Collections.reverse(list); //Flipping does not require sorting Collections.fill(list, 100); //All assigned to 100 } }
6.3 object comparison
- Object implements the Comparable interface (the object class needs to be modified)
– compareTo method: > returns 1, = = returns 0, < returns - 1
– Arrays and Collections automatically call this method when sort ing objects - Create a new Comparator (applicable when the object class cannot be changed)
– compare method: > returns 1, = = returns 0, < returns - 1
– the Comparator comparator submits it as a parameter to the sort method of the tool class
Object implements the Comparable interface (the object class needs to be modified): Code
import java.util.Arrays; public class Person implements Comparable<Person> { String name; int age; public String getName() { return name; } public int getAge() { return age; } public Person(String name, int age) { this.name = name; this.age = age; } public int compareTo(Person another) { int i = 0; i = name.compareTo(another.name); // Use string comparison if (i == 0) { // If the name is the same, compare the age and return the age comparison result return age - another.age; } else { return i; // If the names are different, the result of comparing names will be returned } } public static void main(String... a) { Person[] ps = new Person[3]; ps[0] = new Person("Tom", 20); ps[1] = new Person("Mike", 18); ps[2] = new Person("Mike", 20); Arrays.sort(ps); for (Person p : ps) { System.out.println(p.getName() + "," + p.getAge()); } } }
New Comparator (for cases where the object class cannot be changed): Code
import java.util.Arrays; import java.util.Comparator; public class Person2Comparator implements Comparator<Person2> { public int compare(Person2 one, Person2 another) { int i = 0; i = one.getName().compareTo(another.getName()); if (i == 0) { // If the name is the same, compare the age and return the age comparison result return one.getAge() - another.getAge(); } else { return i; // If the names are different, the result of comparing names will be returned } } public static void main(String[] args) { // TODO Auto-generated method stub Person2[] ps = new Person2[3]; ps[0] = new Person2("Tom", 20); ps[1] = new Person2("Mike", 18); ps[2] = new Person2("Mike", 20); Arrays.sort(ps, new Person2Comparator()); for (Person2 p : ps) { System.out.println(p.getName() + "," + p.getAge()); } } }