@[TOC](第八章. Java数据结构)

第八章. Java数据结构

Java常用数据结构

1. 数组

1.1 声明与定义:

int[] a;/*声明*/
int[5] a;/*错误*/
int[ ] a = new int[100];/*定义*/
  • 数组长度定义时不要求是常量
  • 声明变量时不需要加具体数值,在new的时候才规定

1.2 初始化:

  1. 数字数组初始化时:所有元素都为 0。
  2. boolean 数组初始化:所有元素都为 false。
  3. 字符串数组初试化: 所有字符串都为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主要的数据结构实现类

  1. 列表(List, ArrayList, LinkedList)
  2. 集合(Set, HashSet, TreeSet, LinkedHashSet)
  3. 映射(Map, HashMap, TreeMap, LinkedHashMap)

JCF主要的算法类

  1. Arrays: 对数组进行查找和排序等操作
  2. Collections:对Collection及其子类进行排序和查找操

@[TOC](第八章. Java数据结构)

  • 绿色是列表(List),黄色是集合(Set),蓝色是映射(map)

2.2 Collection 接口

:在 Java 类库中,集合有两个基本接口:Collection 和 Map
@[TOC](第八章. Java数据结构)

@[TOC](第八章. Java数据结构)
@[TOC](第八章. Java数据结构)

2.3 迭代器

:迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型。
@[TOC](第八章. Java数据结构)
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的特点:

  1. 以数组实现的列表,不支持同步
    • List list = Collections.synchronizedList(new ArrayList(…));(实现同步)
  2. 利用索引位置可以快速定位访问
  3. 不适合指定位置的插入、删除操作
  4. 适合变动不大,主要用于查询的数据
  5. 和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 + "纳秒");
	}
}

@[TOC](第八章. Java数据结构)

3.2 LinkedList:

LinkedList的特点:

  1. 以双向链表实现的列表,不支持同步
    • List list = Collections.synchronizedList(new LinkedList(…));
  2. 顺序访问高效,随机访问较差,中间插入和删除高效
  3. 可被当作堆栈、队列和双端队列进行操作
  4. 适用于经常变化的数据

LinkedList的增删,遍历操作:

代码与ArrayList相似

@[TOC](第八章. Java数据结构)

3.3 Vector

  1. 与ArrayList相似
  2. 同步采用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 + "纳秒");
	}
}

@[TOC](第八章. Java数据结构)

4.2 LinkedHashSet

  1. 继承HashSet,也是基于HashMap实现的,可以容纳null元素
  2. 通过一个双向链表维护插入顺序
  3. 不支持同步
    • Set s = Collections.synchronizedSet(new LinkedHashSet(…));
  4. 方法和HashSet基本一致
    • add, clear, contains, remove, size

LinkedHashSet的增删与迭代:

与HashSet 相似

4.3 TreeSet

  1. 基于TreeMap实现的,不可以容纳null元素,不支持同步
    • SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…));
  2. 根据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 + "纳秒");
	}

}

@[TOC](第八章. Java数据结构)

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();
    }
}

@[TOC](第八章. Java数据结构)
升序排列: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
		

	}
}

@[TOC](第八章. Java数据结构)
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

  1. K-V对,K和V都不允许为null
  2. 同步,多线程安全
  3. 无序的
  4. 适合小数据量
    –主要方法:clear, contains/containsValue, containsKey, get,
    put,remove, size

@[TOC](第八章. Java数据结构)

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 + "纳秒");
	}
}

@[TOC](第八章. Java数据结构)

5.2 HashMap

  1. K-V对,K和V都允许为null
  2. 不同步,多线程不安全
    • Map m = Collections.synchronizedMap(new HashMap(…));
  3. 无序的
    –主要方法:clear, containsValue, containsKey, get, put,remove, size

HashMap的增删与遍历:

与HashTable相似

5.3 LinkedHashMap

基于双向链表的维持插入顺序的HashMap

与HashTable相似

@[TOC](第八章. Java数据结构)

5.4 TreeMap

基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出

与HashTable相似

@[TOC](第八章. Java数据结构)

5.5 • Properties

  1. 继承于Hashtable
  2. 可以将K-V对保存在文件中
  3. 适用于数据量少的配置文件
    –继承自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中工具类
:不存储数据,而是在数据容器上,实现高效操作

  1. 排序
  2. 搜索

–Arrays类
–Collections类

6.1 Arrays:处理对象是数组

  1. 排序:对数组排序, sort/parallelSort。
  2. 查找:从数组中查找一个元素, binarySearch。
    –二分查找需要提前排序
  3. 批量拷贝:从源数组批量复制元素到目标数组, copyOf。
  4. 批量赋值:对数组进行批量赋值, fill。
  5. 等价性比较:判定两个数组内容是否相同, 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));
	}
}

@[TOC](第八章. Java数据结构)

6.2 Collections: 处理对象是 Collection及其子类

  1. 排序:对List进行排序,sort。
  2. 搜索:从List中搜索元素,binarySearch
  3. 批量赋值:对List批量赋值,fill。
  4. 最大、最小:查找集合中最大/小值,max,min
  5. 反序:将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 对象比较

  1. 对象实现Comparable接口(需要修改对象类)
    –compareTo方法: > 返回1,==返回0,<返回-1
    –Arrays和Collections在进行对象sort时,自动调用该方法
  2. 新建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());
		}
	}
}

@[TOC](第八章. Java数据结构)

上一篇:A Quick Guide to LaTeX for MCM/ICM


下一篇:PAT-A1041(C/C++代码解析)