第八章. Java数据结构
Java常用数据结构
1. 数组
1.1 声明与定义:
int[] a;/*声明*/
int[5] a;/*错误*/
int[ ] a = new int[100];/*定义*/
- 数组长度定义时不要求是常量
- 声明变量时不需要加具体数值,在new的时候才规定
1.2 初始化:
- 数字数组初始化时:所有元素都为 0。
- boolean 数组初始化:所有元素都为 false。
- 字符串数组初试化: 所有字符串都为null。
- 创建了数组,就不能再改变它的大小。若在运算中改变则使用动态数组-- 数组列表(array list)
1.2.1 初始化方式
中括号{}
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 };
smallPrimes = new int[] { 17, 19, 23, 29, 31, 37};
//逐个初始化
int[] c = new int[2]; //c有2个元素,都是0
c[0] = 10; c[1] = 20; //逐个初始化
int[] anonymous = { 17, 19, 23, 29, 31, 37 };
smallPrimes = anonymous;
1.3 数组拷贝
地址拷贝:两个变量将引用同 一个数组
int[] luckyNumbers = smallPrimes;
1uckyNumbers[5] = 12; /* now smallPrimes[5] is also 12 */
数值拷贝: Arrays 类的 copyOf方法
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
- 如果数组元素是数值型,那么多余的元素将被赋值为 0
- 如果数组元素是布尔型,则将赋值 为 false。
- 相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
1.6 数组遍历
//需要自己控制索引位置
for(int i=0;i<d.length;i++) {
System.out.println(d[i]);
}
//无需控制索引位置
for(int e : d) {
System.out.println(e);
}
1.5 多维数组
多维数组:即数组元素也是数组
不规则数组:数组的每一行有不同的长度。
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概述
JCF(Java容器框架):为表示和操作容器而规定的一种标准体系结构
- 对外的接口:容器中所能存放的抽象数据类型
- 接口的实现:可复用的数据结构
- 算法: 对数据的查找和排序
JCF的集合接口是Collection
- add,contains,remove,size
- iterator
JCF的迭代器接口Iterator
- hasNext
- next
- remove
JCF主要的数据结构实现类
- 列表(List, ArrayList, LinkedList)
- 集合(Set, HashSet, TreeSet, LinkedHashSet)
- 映射(Map, HashMap, TreeMap, LinkedHashMap)
JCF主要的算法类
- Arrays: 对数组进行查找和排序等操作
- Collections:对Collection及其子类进行排序和查找操
- 绿色是列表(List),黄色是集合(Set),蓝色是映射(map)
2.2 Collection 接口
:在 Java 类库中,集合有两个基本接口:Collection 和 Map
2.3 迭代器
:迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型。
Iterator 接口包含 4个方法:
public interface Iterator<E>
{
E next(); //指向下一个迭代器,返回上个元素
boolean hasNext();
void remove();//删除迭代器前的元素值
default void forEachRemaining(Consumer<? super E> action);
}
遍历:
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.在 Java SE 8中,甚至不用写循环。可以调用 forEachRemaining方法并提供一lambda表达式(它会处理一个元素)。
将对迭代器的每一个元素调用这个 lambda 表达式,直到再没有元素为止。
iterator.forEachRemaining(element -> dosomethingwith element);
删除
: remove 之前没有调用 next 将是不合法的
如果想删除两个相邻的元素, 不能直接地这样调用:
it.remove();
it.remove();// Error
必须先调用 next 越过将要删除的元素。
it,remove();
it.next();
it.remove(); // OK
3. 列表List
List:列表
- 有序的Collection
- 允许重复元素
- {1,2,4,{5,2},1,3}
List 主要实现
- ArrayList(非同步)
- LinkedList(非同步)
- Vector(同步)
3.1 ArrayList
ArrayList的特点:
- 以数组实现的列表,不支持同步
• List list = Collections.synchronizedList(new ArrayList(…));(实现同步) - 利用索引位置可以快速定位访问
- 不适合指定位置的插入、删除操作
- 适合变动不大,主要用于查询的数据
- 和Java数组相比,其容量是可动态调整的,ArrayList在元素填满容器时会自动扩充容器大小的50%
ArrayList的增删,遍历操作:
import java.util.ArrayList;
import java.util.Iterator;
//Vector 几乎和ArrayList一样,除了Vector本身是同步的
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); //删除第四个元素,后面元素往前挪动
al.add(3, 9); //将9插入到第4个元素,后面元素往后挪动
System.out.println("======遍历方法=============");
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<Integer> iter1 = al.iterator();
while(iter1.hasNext()){
iter1.next();
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
public static void traverseByIndex(ArrayList<Integer> al)
{
long startTime = System.nanoTime();
System.out.println("============随机索引值遍历==============");
for(int i=0;i<al.size();i++)
{
al.get(i);
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
public static void traverseByFor(ArrayList<Integer> al)
{
long startTime = System.nanoTime();
System.out.println("============for循环遍历==============");
for(Integer item : al)
{
;
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
}
3.2 LinkedList:
LinkedList的特点:
- 以双向链表实现的列表,不支持同步
• List list = Collections.synchronizedList(new LinkedList(…)); - 顺序访问高效,随机访问较差,中间插入和删除高效
- 可被当作堆栈、队列和双端队列进行操作
- 适用于经常变化的数据
LinkedList的增删,遍历操作:
代码与ArrayList相似
3.3 Vector
- 与ArrayList相似
- 同步采用Vector
4. 集合Set
集合 Set
- 确定性:对任意对象都能判定其是否属于某一个集合
- 互异性:集合内每个元素都是无差异的,注意是内容差异,都不重复
- 无序性:集合内的顺序无关
Java中的集合接口Set
- HashSet (基于散列函数的集合,无序,不支持同步)
- LinkedHashSet(基于散列函数和双向链表的集合,插入有序,不
支持同步) - TreeSet (基于树结构的集合,内容可排序的,不支持同步)
4.1 HashSet
基于HashMap实现的,可以容纳null元素, 不支持同步
Set s = Collections.synchronizedSet(new HashSet(…));
- add 添加一个元素
- clear 清除整个HashSet
- contains 判定是否包含一个元素
- remove 删除一个元素 size 大小
- retainAll 计算两个集合交集
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 重复
hs.add(null); //null重复
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循环遍历==============");
for(Integer item : hs)
{
System.out.println(item);
}
System.out.println("============测试集合交集==============");
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");
//交集
set1.retainAll(set2);
System.out.println("交集是 "+set1);
System.out.println("============测试多种遍历方法速度==============");
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<Integer> iter1 = hs.iterator();
while(iter1.hasNext()){
iter1.next();
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
public static void traverseByFor(HashSet<Integer> hs)
{
long startTime = System.nanoTime();
System.out.println("============for循环遍历==============");
for(Integer item : hs)
{
;
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
}
4.2 LinkedHashSet
- 继承HashSet,也是基于HashMap实现的,可以容纳null元素
- 通过一个双向链表维护插入顺序
- 不支持同步
• Set s = Collections.synchronizedSet(new LinkedHashSet(…)); - 方法和HashSet基本一致
• add, clear, contains, remove, size
LinkedHashSet的增删与迭代:
与HashSet 相似
4.3 TreeSet
- 基于TreeMap实现的,不可以容纳null元素,不支持同步
• SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…)); - 根据compareTo方法或指定Comparator排序(内容排序)
- add 添加一个元素
- clear 清除整个TreeSet
- contains 判定是否包含一个元素
- remove 删除一个元素 size 大小
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); 错误,不支持null
ts.add(1000);
ts.add(20);
ts.add(3);
ts.add(40000);
ts.add(5000000);
ts.add(3); //3 重复
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循环遍历==============");
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<Integer> iter1 = hs.iterator();
while(iter1.hasNext()){
iter1.next();
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
public static void traverseByFor(TreeSet<Integer> hs)
{
long startTime = System.nanoTime();
System.out.println("============for循环遍历==============");
for(Integer item : hs)
{
;
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
}
4.4 判断对象重复原则,大小原则
HashSet, LinkedHashSet, TreeSet的元素都只能是对象
HashSet和LinkedHashSet判定元素重复的原则(根据hashcode、equals)
- 判定两个元素的hashCode返回值是否相同,若不同,返回false
- 若两者hashCode相同,判定equals方法,若不同,返回false;否则返回true。
–hashCode和equals方法是所有类都有的,因为Object类有
TreeSet判定元素重复的原则
- 需要元素继承自Comparable接口,覆写两个元素的compareTo方法
代码参考:
Cat类(未覆写hashcode、equals)
Dog类(覆写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();
}
}
升序排列:obj1-obj2>0的话返回1,说明按照从小到大排序
降序排列:obj1-obj2>0的话返回-1,说明按照从大到小排序
Cat,Dog,Tiger测试:
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未覆写hashcode与equals,不能在HashSet中判断相同
Dog已覆写hashcode与equals,能在HashSet中判断相同
Tiger未覆写hashcode与equals,不能在HashSet中判断相同,但覆写了Comparable接口中的compareTo方法,能够在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映射
- 数学定义:两个集合之间的元素对应关系。
- 一个输入对应到一个输出
- {1,张三},{2,李四},{Key,Value},键值对,K-V对
Java中Map
- Hashtable(同步,慢,数据量小)
- HashMap(不支持同步,快,数据量大)
- Properties (同步,文件形式,数据量小)
5.1 Hashtable
- K-V对,K和V都不允许为null
- 同步,多线程安全
- 无序的
- 适合小数据量
–主要方法:clear, contains/containsValue, containsKey, get,
put,remove, size
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); 编译不报错 运行报错
//ht.put(null,1); 编译报错
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"); //更新覆盖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迭代器遍历==============");
Integer key;
String value;
Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry<Integer, String> entry = iter.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
//System.out.println("Key:" + key + ", Value:" + value);
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
public static void traverseByKeySet(Hashtable<Integer,String> ht)
{
long startTime = System.nanoTime();
System.out.println("============KeySet迭代器遍历==============");
Integer key;
String value;
Iterator<Integer> iter = ht.keySet().iterator();
while(iter.hasNext()) {
key = iter.next();
// 获取value
value = ht.get(key);
//System.out.println("Key:" + key + ", Value:" + value);
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(duration + "纳秒");
}
}
5.2 HashMap
- K-V对,K和V都允许为null
- 不同步,多线程不安全
• Map m = Collections.synchronizedMap(new HashMap(…)); - 无序的
–主要方法:clear, containsValue, containsKey, get, put,remove, size
HashMap的增删与遍历:
与HashTable相似
5.3 LinkedHashMap
基于双向链表的维持插入顺序的HashMap
与HashTable相似
5.4 TreeMap
基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出
与HashTable相似
5.5 • Properties
- 继承于Hashtable
- 可以将K-V对保存在文件中
- 适用于数据量少的配置文件
–继承自Hashtable的方法:clear, contains/containsValue, containsKey,
get, put,remove, size
–从文件加载的load方法, 写入到文件中的store方法
–获取属性 getProperty ,设置属性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;
//关于Properties类常用的操作
public class PropertiesTest {
//根据Key读取Value
public static String GetValueByKey(String filePath, String key) {
Properties pps = new Properties();
try {
InputStream in = new BufferedInputStream (new FileInputStream(filePath));
pps.load(in); //所有的K-V对都加载了
String value = pps.getProperty(key);
//System.out.println(key + " = " + value);
return value;
}catch (IOException e) {
e.printStackTrace();
return null;
}
}
//读取Properties的全部信息
public static void GetAllProperties(String filePath) throws IOException {
Properties pps = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream(filePath));
pps.load(in); //所有的K-V对都加载了
Enumeration en = pps.propertyNames(); //得到配置文件的名字
while(en.hasMoreElements()) {
String strKey = (String) en.nextElement();
String strValue = pps.getProperty(strKey);
//System.out.println(strKey + "=" + strValue);
}
}
//写入Properties信息
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);
//从输入流中读取属性列表(键和元素对)
pps.load(in);
//调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
//强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
OutputStream out = new FileOutputStream(filePath);
pps.setProperty(pKey, pValue);
//以适合使用 load 方法加载到 Properties 表中的格式,
//将此 Properties 表中的属性列表(键和元素对)写入输出流
pps.store(out, "Update " + pKey + " name");
out.close();
}
public static void main(String [] args) throws IOException{
System.out.println("写入Test.properties================");
WriteProperties("Test.properties","name", "12345");
System.out.println("加载Test.properties================");
GetAllProperties("Test.properties");
System.out.println("从Test.properties加载================");
String value = GetValueByKey("Test.properties", "name");
System.out.println("name is " + value);
}
}
6. 工具类
JCF中工具类
:不存储数据,而是在数据容器上,实现高效操作
- 排序
- 搜索
–Arrays类
–Collections类
6.1 Arrays:处理对象是数组
- 排序:对数组排序, sort/parallelSort。
- 查找:从数组中查找一个元素, binarySearch。
–二分查找需要提前排序 - 批量拷贝:从源数组批量复制元素到目标数组, copyOf。
- 批量赋值:对数组进行批量赋值, fill。
- 等价性比较:判定两个数组内容是否相同, 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("===============测试排序================");
System.out.println("排序前");
for(int i=0;i<a.length;i++) {
System.out.print(a[i] + ",");
}
System.out.println();
System.out.println("排序后");
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("===========测试查找============");
System.out.println("10000 的位置是" + 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("===========测试拷贝前五个元素============");
System.out.print("源数组:");
for(int i=0;i<a.length;i++)
{
System.out.print(a[i] + ",");
}
System.out.println();
System.out.print("目标数组:");
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("===========测试批量赋值============");
System.out.print("数组赋值后:");
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: 处理对象是 Collection及其子类
- 排序:对List进行排序,sort。
- 搜索:从List中搜索元素,binarySearch
- 批量赋值:对List批量赋值,fill。
- 最大、最小:查找集合中最大/小值,max,min
- 反序:将List 反序排列,reverse
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);
// 排序
Collections.sort(list);
// 检索
System.out.println("元素所在的索引值是:" + Collections.binarySearch(list, 12));
//最大最小
System.out.println("最大值:" + Collections.max(list));
System.out.println("最小值:" + Collections.min(list));
Collections.reverse(list); //翻转不需要用到排序
Collections.fill(list, 100); //全部赋值为100
}
}
6.3 对象比较
- 对象实现Comparable接口(需要修改对象类)
–compareTo方法: > 返回1,==返回0,<返回-1
–Arrays和Collections在进行对象sort时,自动调用该方法 - 新建Comparator(适用于对象类不可更改的情况)
–compare方法: > 返回1,==返回0,<返回-1
–Comparator比较器将作为参数提交给工具类的sort方法
对象实现Comparable接口(需要修改对象类):代码
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); // 使用字符串的比较
if (i == 0) {
// 如果名字一样,比较年龄, 返回比较年龄结果
return age - another.age;
} else {
return i; // 名字不一样, 返回比较名字的结果.
}
}
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());
}
}
}
新建Comparator(适用于对象类不可更改的情况):代码
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) {
// 如果名字一样,比较年龄,返回比较年龄结果
return one.getAge() - another.getAge();
} else {
return i; // 名字不一样, 返回比较名字的结果.
}
}
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());
}
}
}