JAVA集合类入门自学笔记

  • Post author:
  • Post category:java




JAVA集合

在这里插入图片描述



一、集合概念

  1. 集合定义:对象的容器,类似数组。
  2. 与数组的区别

    • 数组长度固定,集合长度不固定
    • 数组可以存储基本类型和引用类型,

      集合只能存储引用类型

      (基本类型可以装箱后再存进集合)



二、Collection体系集合

在这里插入图片描述



1. Collection父接口/根接口

【特点】

  • 一组任意类型的对象,

    无序,无下标,不能重复

【常用方法&案例——集合元素为字符串】

	public static void main(String[] args) {
		//【创建集合】(创建一个Collection对象,但是其直接子类List和Set都是接口不能实例化,所以选择更下层子类)
		Collection collection = new ArrayList();//也可以new ArrayList(20) 指定容量
		
		//【添加元素】
		collection.add("apple");
		collection.add("banana");	
		collection.add("orange");
		
		//【统计集合元素个数】
		System.out.println("元素个数:" + collection.size());
		
		//【输出集合】
		System.out.println(collection);	
		
		//【删除元素】
		//collection.clear();					//清空集合
		//collection.removeAll(collection);		//清空集合
		//collection.remove("banana");			//删除指定元素
		
		//【遍历元素★★★】
		//方法一:增强for(不能普通for,因为没有下标呀!)
		System.out.println("方法一:增强for遍历集合:");	
		for (Object object : collection) {
			System.out.println(object);	
		}
		//方法二:迭代器Iterator接口(专用遍历集合),iterator()方法返回在此 collection 的元素上进行迭代的迭代器
		//Iterator中包含三个方法:Hasnext()、next()、remove()
		System.out.println("方法二:迭代器遍历集合:");	
		Iterator it = collection.iterator();
		while(it.hasNext()) {
			String s = (String) it.next();//因为已知存放的是string对象
			System.out.println(s);	
			//collection.remove(s);	【注】:迭代器工作时,不能用collection的remove方法
			//it.remove();			【注】:迭代器工作时,要用迭代器自己的remove方法
		}
		
		//【判断】
		System.out.println(collection.isEmpty());			//是否为空?
		System.out.println(collection.contains("peach"));	//是否包含指定元素?
	}

【常用方法&案例——集合元素为自创的class对象】

	public static void main(String[] args) {
		//新建Collection和学生类对象
		Collection collection = new ArrayList();
		Student s1 = new Student("张三",24);
		Student s2 = new Student("李四",22);
		Student s3 = new Student("王五",19);
		
		//向collection添加数据
		collection.add(s1);
		collection.add(s2);
		collection.add(s3);
		System.out.println("元素个数"+collection.size());
		System.out.println(collection);
		
		//从collection删除数据(不会删除s1对象本身,因为集合里存的是地址)
		collection.remove(s1);
		//collection.clear();	//清空collection
		System.out.println("元素个数"+collection.size());
		System.out.println(collection);
		
		//遍历
		System.out.println("方法一:增强for遍历集合:");	
		for (Object object : collection) {
			System.out.println(object);	
		}
		System.out.println("方法二:迭代器遍历集合:");	
		Iterator it = collection.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}



2. List子接口

【特点】


  • 有序,有下标,可以重复

【List通用——方法&案例】

public static void main(String[] args) {
		//【创建集合】List本身是抽象接口,需要用子类ArrayList创建
		List list = new ArrayList<>();
		
		//【添加元素】
		list.add("apple");
		list.add("HuaWei");
		list.add("RedMi");
		list.add(1, "Realme");//在指定位置添加元素(该位置原先的元素向后移动)
		System.out.println("元素个数:" + list.size());
		System.out.println(list);
		
		//【删除元素】
		//list.remove(0);						//删除指定“下标”的元素,即apple
		//list.remove(list.indexOf("apple"));	//删除指定“值”的元素(先获取下标)
		//list.remove("apple");			//删除指定“值”的元素
		//list.clear();							//清空
		//System.out.println("元素个数:" + list.size());
		//System.out.println(list);
		
		//【遍历】
		//方法一:for遍历,用整型i,做下标
		System.out.println("方法一:for遍历");
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		//方法二:增强for遍历
		System.out.println("方法二:增强for遍历");
		for (Object object : list) {
			System.out.println(object);
		}
		//方法三:迭代器遍历
		System.out.println("方法三:迭代器遍历");
		Iterator it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		//方法四:列表迭代器遍历(结合了List的特点:1.获得迭代器的下标位置 2.按指定方向遍历 3.在指定位置增删改)
		ListIterator lit = list.listIterator();
		System.out.println("方法四:列表迭代器从前往后");
		while(lit.hasNext()) {
			System.out.println(lit.nextIndex()+":"+lit.next());
		}
		System.out.println("方法四:列表迭代器从后往前(需要先移动指针)");
		while(lit.hasNext())lit.next();		//移动指针
		while(lit.hasPrevious()) {
			System.out.println(lit.previousIndex()+":" + lit.previous());
		}
		
		//【判断】
		System.out.println(list.isEmpty());			//是否为空?
		System.out.println(list.contains("OnePlus"));	//是否包含指定元素?		
		
		//【获取位置】
		System.out.println("华为的位置是:" + list.indexOf("HuaWei"));
		
		//【返回子集合】
		System.out.println(list.subList(1, 3));//前闭后开,返回的下标为1和2
	}

【List的实现类——三个子类】

  • ArrayList

    • 数组结构
    • 查询快(下标随即查询),增删慢(要移动元素)
    • 效率高,但线程不安全
  • Vector

    • 数组结构
    • 查询快(下标随即查询),增删慢(要移动元素)
    • 有加锁,线程安全,但效率低了
    • 新增了element概念(组件)
  • LinkedList

    • 链表结构实现(双向链表)
    • 增删快,查询慢



★★★ ArrayList

  • 实现基本和上面的List相同
  • 源码分析

    1. 默认初始容量:DEFAULT_CAPACITY = 10(添加完第一个元素之后的默认容量)
    2. 创建后的容量:未添加元素时是空的,Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
    3. 存放元素的数组:Object[] elementData
    4. 实际元素个数:Size



Vector

public static void main(String[] args) {
		Vector vector = new Vector(10,2);
		vector.add("apple");
		vector.add("HuaWei");
		vector.add("VIVO");
		vector.add("OPPO");
		
		//返回指定索引处的组件。
		System.out.println(vector.elementAt(0));
		
		//删除指定下标的组件
		vector.remove(0);//继承自List
		vector.removeElementAt(0);//Vector特有的
		//删除指定组件
		vector.remove(vector.elementAt(0));
		vector.removeElement(vector.elementAt(0));//Vector特有的
		
		//【遍历】使用枚举器
		System.out.println("使用枚举器遍历:");
		Enumeration en = vector.elements();		//返回此向量的组件的枚举。
		while(en.hasMoreElements()) {
			Object o = en.nextElement();
			System.out.println(o);
		}
	}



LinkedList

	public static void main(String[] args) {
		LinkedList linkedlist = new LinkedList();
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24);
		
		//【添加元素】(队满时:ADD返回异常;OFFER返回false)
		//ADD
		linkedlist.add(s1);//尾部添加元素
		linkedlist.add(0,s2);
		linkedlist.addFirst(s3);
		//OFFER
		linkedlist.offer(s4);//尾部添加元素
		linkedlist.offerFirst(s5);
		
		//【获取元素】(队空时:Get/Element返回异常,PEEK返回NULL)(源码中设定好的)
		//Get
		linkedlist.get(1);//返回指定位置的元素
		linkedlist.getLast();
		linkedlist.getFirst();
		//Element
		linkedlist.element();//返回首部元素
		//PEEK
		linkedlist.peek();//返回首部元素
		linkedlist.peekFirst();
		linkedlist.peekLast();
		
		//【删除元素】(队空时:REMOVE返回异常;POLL返回NULL)(源码中设定好的)
		//REMOVE
		linkedlist.remove();//删除首部元素
		linkedlist.remove(1);
		//POLL
		linkedlist.poll();//删除首部元素
		linkedlist.pollFirst();
		linkedlist.pollLast();
		
		//【迭代器遍历】
		System.out.println("正向:");
		Iterator it = linkedlist.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println("反向:");
		Iterator descit = linkedlist.descendingIterator();
		while(descit.hasNext()) {
			System.out.println(descit.next());
		}
			
		System.out.println("元素个数:" + linkedlist.size());
		System.out.println(linkedlist);
		System.out.println(linkedlist.contains(s3));
	}



3. Set子接口

【特点】

  • 一组任意类型的对象,

    无序,无下标,不能重复
  • Set中的方法全都是从Collection中继承下来的
  • Set也是个接口,要创建对象的话都是需要子类来实现

【常用方法】

public static void main(String[] args) {
		//【创建集合】用于存放String的HashSet集合
		Set<String> set = new HashSet<>();
		
		//添加数据
		set.add("HuaWei");
		set.add("Apple");
		set.add("RedMi");
		set.add("RealMe");	
		
		//【删除数据】Set没有下标,只能用Object来删除
		set.remove("HuaWei");
		
		System.out.println("数据个数:" + set.size());
		System.out.println(set.toString());
		
		//【遍历】
		//1.增强for
		for (String string : set) {
			System.out.println(string);
		}
		//2.Iterate迭代器
		Iterator it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());			
		}
		
		//【判断】
		System.out.println(set.contains("Apple"));
	}



★★★ HashSet

【特点】

  • 添加和删除元素时,要使用HashCode和Equals进行判断

【常用方法(几乎同Set)】

public static void main(String[] args) {
		//【新建HashSet】泛型设定为String类
		HashSet<Student> students = new HashSet<>();
		
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24);
		
		
		students.add(s1);
		students.add(s2);
		students.add(s3);
		students.add(s4);
		students.add(s5);
		
		//添加一个信息相同的对象,可以成功,因为对象不同,HashCode不同
		//若想不让信息相同的添加进来,可以修改Student类的equals方法和HashCode方法(Alt + s就可以找到自动生成)
		Student s6 = new Student("陆七",24);
		students.add(s6);
		System.out.println("s5:" + s5.hashCode() + " s6:"+s6.hashCode());
		
		System.out.println("元素个数:" + students.size());
		System.out.println(students.toString());
	}



//重写Student类中的equals方法和HashCode方法
	@Override
	//用name和age来生成HashCode
	public int hashCode() {
		int hc1 = this.name.hashCode();
		int hc2 = this.age;
		return hc1 + hc2 ; 
	}
	

	@Override
	//用name和age来判断Equals
	public boolean equals(Object obj) {
		//是否为同一个对象
		if(this==obj) {
			return true;
		}
		//是否为空
		if(obj==null) {
			return false;
		}
		//是否是Student类型
		if(obj instanceof Student) {
			Student s = (Student)obj;
			//比较姓名
			if(this.name.equals(s.getName())&&this.age==s.getAge()) {
				return true;
			}
		}
		//均不满足
		return false;
	}

【存储元素的过程】

  • 先调用hashCode(),若相同,再用equals()与该位置的对象比较。

  • 若相等则说明对象已存在,不必添加新的;若不相等,则使用拉链法,在同一位置链接新对象。

  • hashCode()与equals()具有上述的联动关系,所以equals()方法重写时,通常也要将hashCode()进行重写,使得这两个方法始终满足相关的约定。



TreeSet

【特点】

  • 红黑树存储(二叉排序树BST → 平衡二叉树AVL 元素不重复)
  • 实现了Sorted接口,对集合元素排序

  • 元素对象类必须实现Comparable接口,指定排序规则,否则无法向SET添加元素

  • 通过Comparable里的CompareTo确定是否为重复元素,且能体现出大小关系,完成排序树
  • 添加和删除元素时,不需要HashCode和Equals,仅用CompareTo

【实现】

//1. 在元素类中使用Comparable接口的CompareTo方法,进行元素比较
public static void main(String[] args) {
    	//创建TreeSet,存储Student类对象
		TreeSet<Student> treeSet = new TreeSet<>();
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24); 
		treeSet.add(s1);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
    	treeSet.remove(new Student("张三",20));//通过重写的compareTo,可以成功删除
		System.out.println(treeSet.size());
		System.out.println(treeSet.toString());
	}

//Student类【必须实现Comparable接口里的CompareTo方法】
public class Student implements Comparable<Student> {
	String name;
	int age;
    
    //重写Comparable接口的compareTo方法,制定比较规则【必须保留比较的差值,从而体现大小关系】
	@Override
	public int compareTo(Student o) {
		return this.age - o.getAge();
	}	
}
//2.使用匿名内部类,在创建TreeSet时定义一个Comparator比较器,就可以不必在元素类中重写CompareTo
public static void main(String[] args) {
		//创建TreeSet时,使用匿名内部类创建Comparator比较器,用于制定Student类元素的比较规则
		TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				return o1.getAge() - o2.getAge();
			}
		});
		
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24); 
		treeSet.add(s1);
		treeSet.add(s2);
		treeSet.add(s3);
		treeSet.add(s4);
		treeSet.add(s5);
		System.out.println(treeSet.size());
		System.out.println(treeSet.toString());
		treeSet.remove(new Student("ABC",20));//通过Comparator比较器(比较年龄),可以成功删除
		System.out.println(treeSet.size());
		System.out.println(treeSet.toString());	
	}

【案例】

/**
 * 将几个字符串从短到长排序,长短相同的按照字母顺序排序
 */
public class Demo13_TreeSet_Test {
	public static void main(String[] args) {
		//创建TreeSet时,用匿名内部类定义Comparator比较器,先比较String的长度,再比较字母顺序
		TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				int n1 = o1.length() - o2.length();
				int n2 = o1.compareTo(o2);
				return n1==0?n2:n1;
			}
		});
		
		System.out.println("请输入几条字符串(输入“终止”即可终止输入)");
		while(true) {
			Scanner scanner = new Scanner(System.in);
			String s = scanner.next();
			if(s.compareTo("终止")==0) {
				break;
			}
			treeSet.add(s);
		}
		System.out.println(treeSet.size());
		System.out.println(treeSet.toString());		
	}
}



4. 泛型

  • 概念:

    • 泛型用于限制类/接口/方法/中的元素类型。允许程序在创建

      集合

      时指定集合

      元素的类型(必须是引用类型)

      ,Java的参数化类型被称为泛型(Generic)。例如 List,表明 该List只能保存字符串类型的对象。泛型的本质是参数化类型(所操作的数据类型被指定为一个参数)
  • 好处:

    • 1.提高代码重用性
    • 2.防止类型转换异常,提高代码安全性

【泛型类】

/**
 * 泛型类 语法:类名<字母T> E是类型占位符,表示一种“引用类型”
 */
class MyGeneric<T> {
	// 1.作为变量
	T t;

	// 2.作为方法参数
	public void show(T x) {
		System.out.println(x);
	}

	// 3.作为方法返回值
	public T getT() {
		return t;
	}
}

public class Demo7_Generic {
	public static void main(String[] args) {
		
		//令泛型为String类型
		MyGeneric<String> mygeneric = new MyGeneric<>();
		mygeneric.t = "Hello";
		mygeneric.show(mygeneric.getT());
		
		//令泛型为Integer类型
		MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
		myGeneric2.t = 123;
		myGeneric2.show(myGeneric2.getT());
	}
}

【泛型接口】

//泛型接口的定义
public interface Generical_Interface<T> {
	T ShowT(T x);
}
//先给定接口的类型:String
public class Demo8_Generic_interface implements Generical_Interface<String>{
	//重写接口方法,也要先给定类型:String
    public String ShowT(String x) {
		return "Show:" + x;
	}
	
	public static void main(String[] args) {
		Demo8_Generic_interface test = new Demo8_Generic_interface();
		String  s = test.ShowT("good job");
		System.out.println(s);	
	}
}
//先不给接口类型,同时把类也定义为泛型类
public class Demo8_Generic_interface<T> implements Generical_Interface<T>{
	//重写接口方法,也不给定类型
    public  T ShowT(T x) {
		return x;
	}
	
	public static void main(String[] args) {
        //创建对象时才定义类型
		Demo8_Generic_interface<String> test = new Demo8_Generic_interface<>();
		String  s = test.ShowT("good job");
		System.out.println(s);	
	}
}

【泛型方法】

//在非泛型类中,定义泛型方法
class MyGeneric2{
	//泛型方法,返回String
	public <T> String Show(T t){
		System.out.println("Show" + t);
		return "Show" + t;
	}
	//泛型方法,返回T
	public <T> T GetT(T t) {
		return t;
	}
    //泛型方法,返回void
    public <T> void TypeOfT(T t){
		System.out.println(t.getClass());
	}
}

//泛型方法调用,可以不用特意声明类型
public static void main(String[] args) {
		MyGeneric2 myGeneric2 = new MyGeneric2();
		myGeneric2.Show("AWD");//输入String,即T为String
		myGeneric2.Show(100);//输入Integer,即T为Integer
    	myGeneric2.<String>Show("200");//声明了类型为String,参数只能是String了
    	myGeneric2.TypeOfT(123);
}

【泛型集合】

//使用泛型前
public static void main(String[] args) {
	ArrayList arraylist = new ArrayList<>();
    arraylist.add("HuaWei");
    arraylist.add("RedMi");
    arraylist.add(200);
    arraylist.add(80);
    
    //按Object输出,一切正常,因为String和Integer都是Object的子类
    for(Object object : arraylist){
        System.out.println(object);
    }
    
    //想按String输出:此时Integer转换String会报错
    for(Object object : arraylist){
        System.out.println((String)object);
    }    
}
//使用泛型后
public static void main(String[] args) {
    //给集合设定,只能存放String对象
	ArrayList<String> arraylist = new ArrayList<>();
    //添加元素
    arraylist.add("HuaWei");
    arraylist.add("RedMi");
    arraylist.add(200);//不是String,add时会报错
    
    for(Object object : arraylist){
        System.out.println(object);
    }
}

【泛型与Object的区别】

  • 提问:既然Object是最高级的父类,可以代表任何类,泛型T也可以代表任何类,那么二者有何区别呢?
  • 回答:

    • Object:Object类的对象始终是Object类,如果要变成其他类需要强制转换
    • 泛型:泛型的T被赋予了某一类型后,直接就是该类型了,不需要强制类型转换。
  • 泛型可以有效防止类型转换异常,因为T确定后,类型就锁定了;Object可能会被转化成其他的。



三、Map体系集合

在这里插入图片描述



1. Map父接口/根接口

【特点】

  • 用于存储一对数据(Key-Value)
  • 键Key:无序无下标,不允许重复
  • 值Value:无序无下标,允许重复

【常用方法&案例】

	public static void main(String[] args) {
		//创建Map,因为Map本身是接口,必须借助子类来实现
		Map<String, String> map = new HashMap<>();
		
		//【添加元素】(按对儿来添加)
		map.put("cn", "Zhong");
		map.put("UK", "Ying");
		map.put("USA", "Mei");
		map.put("JP", "Ri");
		map.put("cn","中");//键重复值不重复,会覆盖前键原先的值
		map.put("US", "Mei");//键不重复值重复,正常添加
		
		//【移除元素】(按键来移除)
		map.remove("US");

		//【遍历】
		//3.1使用KeySet(),返回所有Key的Set集合,然后对其增强for
		System.out.println("【KeySet() + 增强for】");
		Set<String> keyset =map.keySet();
		for (String string : keyset) {
			System.out.println(string + "=" +map.get(string) );
		}
		
		//3.2使用entrySet(),返回一个Set集合,集合中的一个元素是一个键值对,然后对其用增强for遍历
		System.out.println("【entrySet() + 增强for】");
		Set<Map.Entry<String, String>> entSet= map.entrySet();
		for (Entry<String, String> entry : entSet) {
			System.out.println(entry);
		}
		//3.2使用entrySet(),返回一个Set集合,集合中的一个元素是一个键值对,然后对其用迭代器遍历
		System.out.println("【entrySet() + 迭代器】");
		Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		
		//【判断】
		System.out.println(map.isEmpty());
		System.out.println(map.containsKey("cn"));//区分大小写
		System.out.println(map.containsValue("Ri"));//区分大小写
	}



2. ★★★ HashMap子接口

【特点】

  • 线程不安全,效率高
  • Key和Value允许为NULL
  • 默认初始容量为16(未添加元素时为0)
  • 加载因子:触发扩容的阈值(初始16,加载因子0.75,那么到12个元素触发扩容,每次变成2倍)

【常用方法&案例】

public static void main(String[] args) {
		HashMap<Student, String> hashmap = new HashMap<>(); 
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24);
		
		//【添加元素】给HashMap添加Student类元素
		hashmap.put(s1, "张");
		hashmap.put(s2, "李");
		hashmap.put(s3, "王");
		hashmap.put(s4, "马");
		hashmap.put(s5, "陆");	
		//按如下方法也能添加成功,因为背后是使用Key的HashCode和Equals判断是否重复。需要重写。
		hashmap.put(new Student("陆七",24), "陆");
		
		//【移除】
		hashmap.remove(s2);
		
		//【遍历keySet】
		Set<Student> keySet = hashmap.keySet();
		for (Student student : keySet) {
			System.out.println(student.toString() + hashmap.get(student));
		}
		//【遍历entrySet】
		for (Entry<Student, String> entry : hashmap.entrySet()) {
			System.out.println(entry);
		}
		
	}

【源码分析】

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;	//初始默认容量(1左移4位,2^4=16)
static final int MAXIMUM_CAPACITY = 1 << 30;	//HashMap数组的最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;	//默认加载因子
static final int TREEIFY_THRESHOLD = 8; //链表大于8时,且元素个数大于64时,调整为红黑树
static final int UNTREEIFY_THRESHOLD = 6;	//链表小于6时,调整回链表

【与HashSet的关系】

  • HashSet就是使用的HashMap,让Key储存元素内容



3. Properties集合

【特点】

  • 是HashTable的子类(HashTable线程安全且效率低)
  • 要求Key和Value都是String
  • 可以保存在流中,或从流中加载
  • 通常用于配置文件的读取



4.TreeMap子接口

【按KEY排序】

  • 比较的对象是Key或Key中的某元素
  • 需要在“Key的类”中继承Comparable接口,并重写“Key类对象”的CompareTo方法
//【Key是student类对象】在student类中继承comparable并重写compareTo,改成年龄排序
	public static void main(String[] args) {
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24);
		TreeMap<Student, String> treeMap = new TreeMap<>();
		treeMap.put(s1, "张");
		treeMap.put(s2, "李");
		treeMap.put(s3, "王");
		treeMap.put(s4, "马");
		treeMap.put(s5, "陆");
		System.out.println(treeMap);
	}

【按Value排序】

  • 比较的对象是Value或Value中的某元素
  • 实际上TreeMap本身没有被改变,只是创建了一个新的ArrayList存放按Value排序的entry
public static void main(String[] args) {
		Student s1 = new Student("张三",20);
		Student s2 = new Student("李四",17);
		Student s3 = new Student("王五",22);
		Student s4 = new Student("马六",19);
		Student s5 = new Student("陆七",24);
		TreeMap<Student,String> treeMap = new TreeMap<>();
		treeMap.put(s1, "001");
		treeMap.put(s2, "009");
		treeMap.put(s3, "008");
		treeMap.put(s4, "002");
		treeMap.put(s5, "005");
		
		//1.创建一个ArrayList,用来存放treeMap的EntrySet,
		List<Map.Entry<Student, String>> entryList = new ArrayList<>(treeMap.entrySet());
		
		//2.对这个ArrayList排序,用匿名内部类指定排序规则
		Collections.sort(entryList, new Comparator<Map.Entry<Student, String>>(){
			@Override
			public int compare(Entry<Student, String> o1, Entry<Student, String> o2) {		
				return o1.getValue().compareTo(o2.getValue());
			}	
		});
		//3.输出这个ArrrayList,按Value学号排序
		System.out.println("按Value学号排序:");
		System.out.println(entryList);
		
		System.out.println("按Key年龄排序:");
		System.out.println(treeMap.entrySet());
	}



四、Collections工具类

public static void main(String[] args) {
		ArrayList<Integer> arrayList = new ArrayList<>();
		arrayList.add(1);
		arrayList.add(15);
		arrayList.add(9);
		arrayList.add(13);
		arrayList.add(3);
		System.out.println("初始:" + arrayList);
		
		//shuffle打乱
		Collections.shuffle(arrayList);
		System.out.println("打乱后:" + arrayList);
		
		//sort排序(升序)
		Collections.sort(arrayList);
		System.out.println("sort排序后:" + arrayList);
		
		//reverse反转
		Collections.reverse(arrayList);
		System.out.println("reverse反转后:" + arrayList);
		
		//binarySearch二分查找(前提是有序)
//		Scanner scanner = new Scanner(System.in);
//		System.out.println("二分查找:");
//		int x = scanner.nextInt();
		int x = 9;
		int i = Collections.binarySearch(arrayList, x);
		if(i<0) {
			System.out.println("元素" + x + "未找到");
		}else {
			System.out.println("二分查找"+ x +"的下标:" + i);
		}
		
		//copy复制
		ArrayList<Integer> arrayList2 = new ArrayList<>();
		for(int j=0 ; j<arrayList.size();j++) {//Copy要求源List与目的List的Size相同
			arrayList2.add(0);
		}
		Collections.copy(arrayList2, arrayList);
		System.out.println("copy复制出的:" + arrayList2);
		
		//集合转成数组
		Integer[] arr = arrayList.toArray(new Integer[10]);	
		System.out.println("集合化成数组:" + Arrays.toString(arr));
		
		//数组转成集合
		List<Integer> list= Arrays.asList(arr);
		System.out.println("数组化成集合:" + list);
	}



版权声明:本文为qq_39630007原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。