Java基础知识之集合框架(二)


一、 Set
一个不包含重复元素的 collection。
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。     
           |--HashSet:底层数据结构是哈希表。线程不同步。 
           |--TreeSet:底层数据结构是二叉树。可以对Set集合中的元素进行排序。默认按照字母的自然排序。
Set集合的功能和Collection是一致的。


二、HashSet
特点:
不保证 set 的迭代顺序
特别是它不保证该顺序恒久不变。
HashSet如何保证元素唯一性
底层数据结构是哈希表(元素是链表的数组)
哈希表依赖于哈希值存储
添加功能底层依赖两个方法:
int hashCode()
boolean equals(Object obj)
  执行顺序:
  先看hashCode()值是否相同
  相同:继续走equals()方法
  返回true: 说明元素重复,就不添加
  返回false:说明元素不重复,就添加到集合
  不同:就直接把元素添加到集合
  如果类没有重写这两个方法,默认使用的Object()。一般来说不相同。

public class Dog {
	private String name;
	private int age;
	private String color;
	private char sex;

	public Dog() {
		super();
	}

	public Dog(String name, int age, String color, char sex) {
		super();
		this.name = name;
		this.age = age;
		this.color = color;
		this.sex = sex;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((color == null) ? 0 : color.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + sex;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Dog other = (Dog) obj;
		if (age != other.age)
			return false;
		if (color == null) {
			if (other.color != null)
				return false;
		} else if (!color.equals(other.color))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (sex != other.sex)
			return false;
		return true;
	}

}

public class DogDemo {
	public static void main(String[] args) {
		// 创建集合对象
		HashSet<Dog> hs = new HashSet<Dog>();

		// 创建狗对象
		Dog d1 = new Dog("秦桧", 25, "红色", '男');
		Dog d2 = new Dog("高俅", 22, "黑色", '女');
		Dog d3 = new Dog("秦桧", 25, "红色", '男');
		Dog d4 = new Dog("秦桧", 20, "红色", '女');
		Dog d5 = new Dog("魏忠贤", 28, "白色", '男');
		Dog d6 = new Dog("李莲英", 23, "黄色", '女');
		Dog d7 = new Dog("李莲英", 23, "黄色", '女');
		Dog d8 = new Dog("李莲英", 23, "黄色", '男');

		// 添加元素
		hs.add(d1);
		hs.add(d2);
		hs.add(d3);
		hs.add(d4);
		hs.add(d5);
		hs.add(d6);
		hs.add(d7);
		hs.add(d8);

		// 遍历
		for (Dog d : hs) {
			System.out.println(d.getName() + "---" + d.getAge() + "---"
					+ d.getColor() + "---" + d.getSex());
		}
	}
}
三、 LinkedHashSet
LinkedHashSet:底层数据结构由哈希表和链表组成。
哈希表保证元素的唯一性。
链表保证元素有序。(存储和取出是一致)
 
四、 TreeSet
TreeSet类概述


TreeSet集合的特点:排序和唯一
使用元素的自然顺序对元素进行排序
或者根据创建 set 时提供的 Comparator 进行排序
具体取决于使用的构造方法。 
TreeSet是如何保证元素的排序和唯一性的
底层数据结构是红黑树(红黑树是一种自平衡的二叉树)

保证数据的唯一性的依据:通过compareTo方法的返回值,
是正整数、负整数或零,则两个对象较大、较小或相同。相等时则不会存入。
TreeSet的排序的两种方式
1.自然排序
让元素自身具备比较性
元素需要实现 Comparable 接口,覆盖compareTo()方法
这种方式也称为元素的自然排序或者叫默认排序
2.比较器
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性
在集合初始化时就要有比较方式。
排序时,当主要条件相同时,一定要判断次要条件。
定义一个比较器,将比较器对象作为一个参数传递给TreeSet集合的构造方法
定义一个类实现 Comparator接口,覆盖compare()方法
两种排序都存在的时候,以比较器为主


//如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口
public class Student implements Comparable<Student> {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int compareTo(Student s) {
		// 主要条件 姓名的长度
		int num = this.name.length() - s.name.length();
		// 姓名的长度相同,不代表姓名的内容相同
		int num2 = num == 0 ? this.name.compareTo(s.name) : num;
		// 姓名的长度和内容相同,不代表年龄相同,所以还得继续判断年龄
		int num3 = num2 == 0 ? this.age - s.age : num2;
		return num3;
	}
}


public class TreeSetDemo {
	public static void main(String[] args) {
		// 创建集合对象
		TreeSet<Student> ts = new TreeSet<Student>();

		// 创建元素
		Student s1 = new Student("xuxian", 25);
		Student s2 = new Student("jintaiyan", 27);
		Student s3 = new Student("liuyifei", 29);
		Student s4 = new Student("wangzhuxian", 27);
		Student s5 = new Student("liushishi", 22);
		Student s6 = new Student("juhela", 24);
		Student s7 = new Student("linyuner", 22);
		Student s8 = new Student("zhenxiujing", 29);

		// 添加元素
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		ts.add(s7);
		ts.add(s8);

		// 遍历
		for (Student s : ts) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}


//实现比较器
public class TreeSetDemo {
	public static void main(String[] args) {
	
		// 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象
		// 而匿名内部类就可以实现
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				// 姓名长度
				int num = s1.getName().length() - s2.getName().length();
				// 姓名内容
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
						: num;
				// 年龄
				int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
				return num3;
			}
		});

		// 创建元素
		Student s1 = new Student("xuxian", 25);
		Student s2 = new Student("jintaiyan", 27);
		Student s3 = new Student("liuyifei", 29);
		Student s4 = new Student("wangzhuxian", 27);
		Student s5 = new Student("liushishi", 22);
		Student s6 = new Student("juhela", 24);
		Student s7 = new Student("linyuner", 22);
		Student s8 = new Student("zhenxiujing", 29);

		// 添加元素
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		ts.add(s7);
		ts.add(s8);

		// 遍历
		for (Student s : ts) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}



/*
  编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
  
  分析:
  		A:创建随机数对象
  		B:创建一个HashSet集合
  		C:判断集合的长度是不是小于10
  			是:就创建一个随机数添加
  			否:不搭理它
  		D:遍历HashSet集合
 */
public class HashSetDemo {
	public static void main(String[] args) {
		// 创建随机数对象
		Random r = new Random();

		// 创建一个Set集合
		HashSet<Integer> ts = new HashSet<Integer>();

		// 判断集合的长度是不是小于10
		while (ts.size() < 10) {
			int num = r.nextInt(20) + 1;
			ts.add(num);
		}

		// 遍历Set集合
		for (Integer i : ts) {
			System.out.println(i);
		}
	}
}


/*
 * 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
 * 
 * 分析:
 * 		A:定义学生类
 * 		B:创建一个TreeSet集合
 * 		C:总分从高到底如何实现? 通过比较器	
 * 		D:键盘录入5个学生信息
 * 		E:遍历TreeSet集合
 */
public class TreeSetDemo {
	public static void main(String[] args) {
		// 创建一个TreeSet集合
		TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				// 总分从高到低
				int num = s2.getSum() - s1.getSum();
				// 总分相同的不一定语文相同
				int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
				// 总分相同的不一定数序相同
				int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
				// 总分相同的不一定英语相同
				int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;
				// 姓名还不一定相同呢
				int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())
						: num4;
				return num5;
			}
		});

		System.out.println("学生信息录入开始");
		// 键盘录入5个学生信息
		for (int x = 1; x <= 5; x++) {
			Scanner sc = new Scanner(System.in);
			System.out.println("请输入第" + x + "个学生的姓名:");
			String name = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的语文成绩:");
			String chineseString = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的数学成绩:");
			String mathString = sc.nextLine();
			System.out.println("请输入第" + x + "个学生的英语成绩:");
			String englishString = sc.nextLine();

			// 把数据封装到学生对象中
			Student s = new Student();
			s.setName(name);
			s.setChinese(Integer.parseInt(chineseString));
			s.setMath(Integer.parseInt(mathString));
			s.setEnglish(Integer.parseInt(englishString));

			// 把学生对象添加到集合
			ts.add(s);
		}
		System.out.println("学生信息录入完毕");

		System.out.println("学习信息从高到低排序如下:");
		System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");
		// 遍历集合
		for (Student s : ts) {
			System.out.println(s.getName() + "\t" + s.getChinese() + "\t"
					+ s.getMath() + "\t" + s.getEnglish());
		}
	}
}
五、Collection总结
Collection
|--List 有序,可重复
|--ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高
|--Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低
|--LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高
|--Set 无序,唯一
|--HashSet
底层数据结构是哈希表。
如何保证元素唯一性的呢?
依赖两个方法:hashCode()和equals()
开发中自动生成这两个方法即可
|--LinkedHashSet
底层数据结构是链表和哈希表
由链表保证元素有序
由哈希表保证元素唯一
|--TreeSet
底层数据结构是红黑树。
如何保证元素排序的呢?
自然排序
比较器排序
如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定

4:针对Collection集合我们到底使用谁?
唯一吗?
是:Set
排序吗?
是:TreeSet
否:HashSet
想要一个和存储一致的顺序可以使用LinkedHashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。

否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。

如果你知道用集合,就用ArrayList。

5:在集合中常见的数据结构(掌握)
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序
通常这些常用的集合容器都是不同步的。

六、 Map
Map<K,V>集合的特点:
  将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 
  
    Map集合和Collection集合的区别?
  Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。
  Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的。
  
    注意:
  Map集合的数据结构值针对键有效,跟值无关
  Collection集合的数据结构是针对元素有效
继承体系
Map
            |--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。(命名不规范的一个类)
            |--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。
            |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。
        Map和Set很像。其实Set底层就是使用了Map集合。
    Map集合的功能概述:
 1:添加功能
V put(K key,V value):添加元素。
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
 2:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
 3:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
 4:获取功能
Set<Map.Entry<K,V>> entrySet():将map集合中映射关系存入到set集合中
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合
 5:长度功能
int size():返回集合中的键值对的对数
七、Map集合的遍历
方式1:根据键找值
获取所有键的集合
遍历键的集合,获取到每一个键
根据键找值
方式2:根据键值对对象找键和值
获取所有键值对对象的集合
遍历键值对对象的集合,获取到每一个键值对对象
根据键值对对象找键和值

Entry:其实就是Map中的一个静态内部接口,为什么定义在内部?
因为只有有了Map集合,有了键值对,才会有键值的映射关系。
关系属于Map集合中的一个内部事务,而且该事务在直接访问Map集合中的元素。

//根据键值对对象找键和值
public class MapDemo3 {
	public static void main(String[] args) {
		// 创建集合对象
		Map<String, String> map = new HashMap<String, String>();

		// 创建元素并添加到集合
		map.put("杨过", "小龙女");
		map.put("郭靖", "黄蓉");
		map.put("杨康", "穆念慈");
		map.put("陈玄风", "梅超风");

		// 遍历
		// 获取所有的键
		Set<String> set = map.keySet();
		// 遍历键的集合,获取得到每一个键
		for (String key : set) {
			// 根据键去找值
			String value = map.get(key);
			System.out.println(key + "---" + value);
		}
	}
}
//根据键值对对象找键和值
public class MapDemo4 {
	public static void main(String[] args) {
		// 创建集合对象
		Map<String, String> map = new HashMap<String, String>();

		// 创建元素并添加到集合
		map.put("杨过", "小龙女");
		map.put("郭靖", "黄蓉");
		map.put("杨康", "穆念慈");
		map.put("陈玄风", "梅超风");

		// 获取所有键值对对象的集合
		Set<Map.Entry<String, String>> set = map.entrySet();
		// 遍历键值对对象的集合,得到每一个键值对对象
		for (Map.Entry<String, String> me : set) {
			// 根据键值对对象获取键和值
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key + "---" + value);
		}
	}
}


八、 HashMap
HashMap:是基于哈希表的Map接口实现。
哈希表的作用是用来保证键的唯一性的。

/*
   HashMap<String,String>
   键:String
   值:String
  */
public class HashMapDemo {
	public static void main(String[] args) {
		// 创建集合对象
		HashMap<String, String> hm = new HashMap<String, String>();

		hm.put("it001", "马云");
		hm.put("it003", "马化腾");
		hm.put("it004", "乔布斯");
		hm.put("it005", "张朝阳");
		hm.put("it002", "裘伯君"); 
		hm.put("it001", "比尔盖茨");

		// 遍历
		Set<String> set = hm.keySet();
		for (String key : set) {
			String value = hm.get(key);
			System.out.println(key + "---" + value);
		}
	}
}


/*
  HashMap<Student,String>
  键:Student
  		要求:如果两个对象的成员变量值都相同,则为同一个对象。
  值:String
 */
public class HashMapDemo4 {
	public static void main(String[] args) {
		// 创建集合对象
		HashMap<Student, String> hm = new HashMap<Student, String>();

		// 创建学生对象
		Student s1 = new Student("貂蝉", 27);
		Student s2 = new Student("王昭君", 30);
		Student s3 = new Student("西施", 33);
		Student s4 = new Student("杨玉环", 35);
		Student s5 = new Student("貂蝉", 27);

		// 添加元素
		hm.put(s1, "8888");
		hm.put(s2, "6666");
		hm.put(s3, "5555");
		hm.put(s4, "7777");
		hm.put(s5, "9999");

		// 遍历
		Set<Student> set = hm.keySet();
		for (Student key : set) {
			String value = hm.get(key);
			System.out.println(key.getName() + "---" + key.getAge() + "---"
					+ value);
		}
	}
}

九、 LinkedHashMap
LinkedHashMap:是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。
    由哈希表保证键的唯一性
    由链表保证键盘的有序(存储和取出的顺序一致)
public class LinkedHashMapDemo {
	public static void main(String[] args) {
		// 创建集合对象
		LinkedHashMap<String, String> hm = new LinkedHashMap<String, String>();

		// 创建并添加元素
		hm.put("2345", "hello");
		hm.put("1234", "world");
		hm.put("3456", "java");
		hm.put("1234", "javaee");
		hm.put("3456", "android");

		// 遍历
		Set<String> set = hm.keySet();
		for (String key : set) {
			String value = hm.get(key);
			System.out.println(key + "---" + value);
		}
	}
}

十、 TreeMap
TreeMap:是基于红黑树的Map接口的实现。
public class TreeMapDemo {
	public static void main(String[] args) {
		// 创建集合对象
		TreeMap<String, String> tm = new TreeMap<String, String>();

		// 创建元素并添加元素
		tm.put("hello", "你好");
		tm.put("world", "世界");
		tm.put("java", "爪哇");
		tm.put("world", "世界2");
		tm.put("javaee", "爪哇EE");

		// 遍历集合
		Set<String> set = tm.keySet();
		for (String key : set) {
			String value = tm.get(key);
			System.out.println(key + "---" + value);
		}
	}
}


public class TreeMapDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		TreeMap<Student, String> tm = new TreeMap<Student, String>(
				new Comparator<Student>() {
					@Override
					public int compare(Student s1, Student s2) {
						// 主要条件
						int num = s1.getAge() - s2.getAge();
						// 次要条件
						int num2 = num == 0 ? s1.getName().compareTo(
								s2.getName()) : num;
						return num2;
					}
				});

		// 创建学生对象
		Student s1 = new Student("潘安", 30);
		Student s2 = new Student("柳下惠", 35);
		Student s3 = new Student("唐伯虎", 33);
		Student s4 = new Student("燕青", 32);
		Student s5 = new Student("唐伯虎", 33);

		// 存储元素
		tm.put(s1, "宋朝");
		tm.put(s2, "元朝");
		tm.put(s3, "明朝");
		tm.put(s4, "清朝");
		tm.put(s5, "汉朝");

		// 遍历
		Set<Student> set = tm.keySet();
		for (Student key : set) {
			String value = tm.get(key);
			System.out.println(key.getName() + "---" + key.getAge() + "---"
					+ value);
		}
	}
}
练习、需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
/*
 * 分析:
 * 		A:定义一个字符串(可以改进为键盘录入)
 * 		B:定义一个TreeMap集合
 * 			键:Character
 * 			值:Integer
 * 		C:把字符串转换为字符数组
 * 		D:遍历字符数组,得到每一个字符
 * 		E:拿刚才得到的字符作为键到集合中去找值,看返回值
 * 			是null:说明该键不存在,就把该字符作为键,1作为值存储
 * 			不是null:说明该键存在,就把值加1,然后重写存储该键和值
 * 		F:定义字符串缓冲区变量
 * 		G:遍历集合,得到键和值,进行按照要求拼接
 * 		H:把字符串缓冲区转换为字符串输出
 
 */
public class TreeMapDemo {
	public static void main(String[] args) {
		// 定义一个字符串(可以改进为键盘录入)
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个字符串:");
		String line = sc.nextLine();

		// 定义一个TreeMap集合
		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
		
		//把字符串转换为字符数组
		char[] chs = line.toCharArray();
		
		//遍历字符数组,得到每一个字符
		for(char ch : chs){
			//拿刚才得到的字符作为键到集合中去找值,看返回值
			Integer i =  tm.get(ch);
			
			//是null:说明该键不存在,就把该字符作为键,1作为值存储
			if(i == null){
				tm.put(ch, 1);
			}else {
				//不是null:说明该键存在,就把值加1,然后重写存储该键和值
				i++;
				tm.put(ch,i);
			}
		}
		
		//定义字符串缓冲区变量
		StringBuilder sb=  new StringBuilder();
		
		//遍历集合,得到键和值,进行按照要求拼接
		Set<Character> set = tm.keySet();
		for(Character key : set){
			Integer value = tm.get(key);
			sb.append(key).append("(").append(value).append(")");
		}
		
		//把字符串缓冲区转换为字符串输出
		String result = sb.toString();
		System.out.println("result:"+result);
	}
}


	练习、ArrayList集合嵌套HashMap集合并遍历。
/* 
 需求:
 假设ArrayList集合的元素是HashMap。有3个。
 每一个HashMap集合的键和值都是字符串。

 结果:
 周瑜---小乔
 吕布---貂蝉

 郭靖---黄蓉
 杨过---小龙女

 令狐冲---任盈盈
 林平之---岳灵珊
 */
public class ArrayListIncludeHashMapDemo {
	public static void main(String[] args) {
		// 创建集合对象
		ArrayList<HashMap<String, String>> array = new ArrayList<HashMap<String, String>>();

		// 创建元素1
		HashMap<String, String> hm1 = new HashMap<String, String>();
		hm1.put("周瑜", "小乔");
		hm1.put("吕布", "貂蝉");
		// 把元素添加到array里面
		array.add(hm1);

		// 创建元素1
		HashMap<String, String> hm2 = new HashMap<String, String>();
		hm2.put("郭靖", "黄蓉");
		hm2.put("杨过", "小龙女");
		// 把元素添加到array里面
		array.add(hm2);

		// 创建元素1
		HashMap<String, String> hm3 = new HashMap<String, String>();
		hm3.put("令狐冲", "任盈盈");
		hm3.put("林平之", "岳灵珊");
		// 把元素添加到array里面
		array.add(hm3);

		// 遍历
		for (HashMap<String, String> hm : array) {
			Set<String> set = hm.keySet();
			for (String key : set) {
				String value = hm.get(key);
				System.out.println(key + "---" + value);
			}
		}
	}
}

十一、 Collections


Collections:是针对集合进行操作的工具类,都是静态方法。
  
面试题:
Collection和Collections的区别?
   Collection:是单列集合的顶层接口,有子接口List和Set。
   Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法
  
要知道的方法
   public static <T> void sort(List<T> list):排序 默认情况下是自然顺序。可以传入比较器
   public static <T> int binarySearch(List<?> list,T key):二分查找
   public static <T> T max(Collection<?> coll):最大值
   public static void reverse(List<?> list):反转
   public static void shuffle(List<?> list):随机置换

public class CollectionsDemo {
	public static void main(String[] args) {
		// 创建集合对象
		List<Student> list = new ArrayList<Student>();

		// 创建学生对象
		Student s1 = new Student("xuxian", 25);
		Student s2 = new Student("zhenxiujing", 29);
		Student s3 = new Student("liuyifei", 29);
		Student s4 = new Student("wangzhuxian", 27);
		Student s5 = new Student("linyuner", 22);
		
		// 添加元素对象
		list.add(s1);
		list.add(s2);
		list.add(s3);
		list.add(s4);
		list.add(s5);

		
		// 比较器排序
		Collections.sort(list, new Comparator<Student>() {
			@Override
			public int compare(Student s1, Student s2) {
				int num = s2.getAge() - s1.getAge();
				int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
						: num;
				return num2;
			}
		});

		// 遍历集合
		for (Student s : list) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

十二、 Arrays
        Arrays是用于操作数组的工具类。里边的方法也全是静态的。不需要创建对象。
 
常见方法
1、Lsit<T> asList(T... a):将数组转换为集合
好处:
可以使用集合的思想和方法来操作数组中的元素。
如:contains,get,indexOf,subList等方法。
注意:
a、将数组转换成集合,不可使用集合的增删方法,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
b、如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
c、如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
2、binarySearch():二分查找
  fill():替换方法
  sort():排序方法
 特点:可对数组元素进行相应操作,可以接受除boolean之外的其他各种基本数据类型及有序的引用类型数组的参数,
且还可以对指定元素的范围,并可根据指定比较器进行相应的操作。
 如:sort(T[]a,Comparator<? super T> c)
fill(int[]a,int from,int to)等
3、String toString():可以接收各种数组类型参数,并返回指定数组内容的字符串表现形式。



Collections 中的toArrays()方法
1.指定类型的数组到底要定义多长?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建数组,而是使用传递进来的数组,所以创建一个刚刚好的数组最好。
2.为什么要将集合变数组?
为了限制对元素的操作,不要进行增删。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值