java 之 集合


集合

1、基本数据类型对象包装类
	为了方便操作基本数据类型值,将其封装成了对象,在对象中定义了属性和行为丰富了该数据的操
	作。
	用于描述该对象的类就称为基本数据类型对象包装类。
	byte		Byte
	short		Short
	int			Integer
	long		Long
	float		Float
	double		Double
	char		Character
	boolean		Boolean
	该包装对象主要用于基本类型和字符串之间的转换

	基本类型-->字符串 方法:
		1. 基本类型数值+""
		2. 用String类中的静态方法valueOf(基本类型数值);

	字符串-->基本类型
	1. 使用包装类中的静态方法xxx parseXxx("xxx");
		int parseInt(String str);
		long parseLong(String str);
		boolean parseBoolean(String str);
	只有Character没有parse方法。

	2. 用Integer的静态方法valueOf(String s);

		整数具备不同的进制体现。

			十进制-->其他进制方法:
			String toBinaryString(int i); //二进制
			String toOctalString(int i);	//八进制
			String toHexString(int i);		//十六进制
			String toString(int i,int radix); //i的radix次方进制

	————————————————————————————————————————————————————————————————————
	import java.util.Arrays;
	public class StringSorted {

		/**
		 *对一个字符串中的数值进行从小到大的排序。"20 78 9 -7 88 36 29"
		 */
		public static void main(String[] args) {
			String str = "20 78 9 -7 88 36 29";
			String[] ss = str.split(" +");
			int[] ins = new int[ss.length];
			for (int i = 0; i < ins.length; i++) {
				ins[i] = Integer.parseInt(ss[i]);
			}
			Arrays.sort(ins);
			for(int i:ins)
				System.out.print(i+" ");		
		}
	}
	————————————————————————————————————————————————————————————————————
2、集合类
	
	集合类的由来:
		对象用于封装特有数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。
	集合特点:
		1. 用于存储对象的容器。
		2. 集合的长度是可变的。
		3. 集合中不可以存储基本数据类型值。
	集合容器因为内部的数据结构不同,有多种具体容器。
	不断的向上抽取,就形成了集合框架。

	P.S.
	数组和集合类同是容器,有何不同?
	数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
	数组中可以存储基本数据类型,集合只能存储对象。

3、 List Set

	Collection
		|--List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。
		|--Set:元素不能重复,无序。

		List:特有的常见方法。
		有一个共性特点就是都可以操作角标。
		1、添加
			void add(index,element);
			void addAll(index,collection);
		2、删除
			Object remove(index);
		3、修改
			Object set(index,element);
		4、获取:
			Object get(index);
			int indexOf(object);
			int lastIndexOf(object);
			List subList(from,to);
			List集合可以完成对元素的增删改查。

	PS:
	在迭代器过程中,不要使用集合方法操作元素(增删改),容易出现异常:
			java.util.ConcurrentModificationException。

	可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。
	Iterator 可实现删除功能
	ListIterator 可实现增删改功能功能

	————————————————————————————————————————————————————————————————————
	import java.util.ArrayList;
	import java.util.Iterator;
	import java.util.ListIterator;

	public class CollectIteratorDemo {
		public static void main(String[] args) {
			ArrayList<Integer> al = new ArrayList<Integer>();
			for (int i = 0; i < 10; i++)
				al.add(i);
			System.out.println("al: " + al);
			 for(Iterator<Integer> it = al.iterator() ;
			 it.hasNext();){
			 if(it.next() == 2)
			 it.remove();
			 }
			System.out.println("al: " + al);
			for (ListIterator<Integer> it = al.listIterator(); it.hasNext();) {
				if (it.next() == 2) {
					it.set(8);
					it.add(4);
					it.add(4);
				}
			}
			System.out.println("al: " + al);
		}
	}
	————————————————————————————————————————————————————————————————————
4、 Vector、ArrayList、LinkedList
	List:
		|--Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
		|--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
		|--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
	
	LinkedList方法:
		addFirst();
		addLast();
	jdk1.6版本后新方法:
		offerFirst();	与addFirst方法没有区别。
		offerLast();	与addLast方法没有区别。
	---------------------------------------------------------
	getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
	getLast();

	jdk1.6版本后新方法:
	peekFirst();//获取但不移除,如果链表为空,返回null。
	peekLast();

	--------------------------------------------------------
	removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
	removeLast();

	jdk1.6版本后新方法:
	pollFirst();//获取并移除,如果链表为空,返回null;
	pollLast();
	————————————————————————————————————————————————————————————————————
	import java.util.LinkedList;

	public class StackDemo {

		/**
		 * 请使用LinkedList来模拟一个堆栈或者队列数据结构。 堆栈:先进后出 First In Last Out FILO 队列:先进先出
		 * First In First Out FIFO
		 */
		public static void main(String[] args) {
			StackSimu s = new StackSimu();
			for (int i = 0; i < 5; i++)
				s.push(i);		
			while (!s.isEmpty())
				System.out.println(s.pop());
		}
	}

	class StackSimu {
		private LinkedList<Integer> ll = new LinkedList<Integer>();// 封装一个链表

		public boolean push(int i) {// 进栈
			ll.offerFirst(i);// 添加在头部,在底部
	//		ll.add(i);
			return true;
		}

		public int pop() {// 出栈
			// if(ll.size()>0)
			return ll.removeFirst();
		}

		public boolean isEmpty() {
			return (ll.size() == 0);
		}
	}
	————————————————————————————————————————————————————————————————————

5、Set:
	Set:元素不可以重复,是无序。

	Set接口中的方法和Collection一致。
		|--HashSet:内部数据结构是哈希表,是不同步的。
		|--TreeSet:可以对Set集合中的元素进行排序,是不同步的

	哈希表判断元素相同的原理:
		1. 首先判断两个元素的哈希值是否相同。
			如果相同,再判断两个对象的内容是否相同。

		2. 判断哈希值相同,其实判断的是对象的HashCode()返回的值是否相等。判断内容相同,用的是equals方法。

	P.S.
		如果哈希值不同,不需要判断equals。

6、LinkedHashSet

	HashSet实现数据的唯一性,Linked实现数据的有序性

7、TreeSet

	TreeSet判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。

		TreeSet对元素进行排序的方式一: 让元素自身具备比较功能,元素就需要实现Comparable接口,
	覆盖compareTo方法。

	如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?

	可以使用TreeSet集合第二种排序方式:
		让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
	将该类对象作为参数传递给TreeSet集合的构造函数。

	P.S.
		如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器
	的比较规则为准。

	与TreeSet底层实现比较有关的底层代码

	final int compare(Object k1, Object k2) {
        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
            : comparator.compare((K)k1, (K)k2);
    }
	由此可见,只有当比较器为空时,才会调用对象的自然属性进行比较。比较器是TreeSet的一个成员

	TreeSet集合的底层是二叉树进行
	————————————————————————————————————————————————————————————————————
	import java.util.Comparator;
	import java.util.TreeSet;

	/**
	 * 10、声明类Student,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,
	 *    按照成绩排序输出结果(考虑成绩相同的问题)。
	 */
	public class Test10 {
		public static void main(String[] args) {
			// 创建集合,并传递比较器
			TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

				@Override
				public int compare(Student o1, Student o2) {
					int result = 1;
					if ((result = (o1.getScore() - o2.getScore())) == 0) {// 按分数排序
						if ((result = (o1.getAge() - o2.getAge())) == 0) {// 分数相同时按年龄
							result = o1.getName().compareTo(o2.getName());// 分数、年龄都相同时按姓名排序
						}
					}
					return result;
				}
			});
			// 创建5个对象,并存入集合
			ts.add(new Student("Lucy", 15, 90));
			ts.add(new Student("Lily", 15, 92));
			ts.add(new Student("Pote", 15, 90));
			ts.add(new Student("Scoe", 17, 90));
			ts.add(new Student("Shay", 18, 94));
			// 遍历集合输出
			for (Student s : ts)
				System.out.println(s);
		}
	}
	//声明类Student,包含3个成员变量
	class Student implements Comparable{
		private String name;
		private int age;
		private int score;

		public Student(String name, int age, int score) {
			super();
			this.name = name;
			this.age = age;
			this.score = score;
		}
		
		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 int getScore() {
			return score;
		}
		
		public void setScore(int score) {
			this.score = score;
		}
		
		@Override
		public String toString() {
			return "姓名 :" + name + ",年龄: " + age + ",分数: " + score;
		}

		@Override
		public int compareTo(Object o) {
			return -1;
		}
	}
	————————————————————————————————————————————————————————————————————
8、Map
	Map:一次添加一对元素,Collection一次添加一个元素。
	Map也称为双列集合,Collection集合称为单列集合。
	其实Map集合中存储的就是键值对。
	map集合中必须保证键的唯一性。

	P.S. 关于泛型相关的知识请参看Java高级知识笔记:http://bbs.itheima.com/thread-107670-1-1.html。
	常用方法:
	1、添加
		value put(key,value):返回前一个和key关联的值,如果没有返回null。
	2、删除
		void clear():清空map集合。
		value remove(Object key):根据指定的key删除这个键值对。
	3、判断
		boolean containsKey(key);
		boolean containsValue(value);
		boolean isEmpty();
	4、获取
		value get(key):通过键获取值,如果没有该键返回null。
			可以通过返回null,来判断是否包含指定键。
		int size():获取键值对个数。
	5、遍历Map的方法:

		Set<Map.Entry<K,V>> entrySet() 
          返回此映射中包含的映射关系的 Set 视图。 

		Set<K> keySet() 
          返回此映射中包含的键的 Set 视图。 
		
		Collection<V> values() 
          返回此映射中包含的值的 Collection 视图。 
	
	Map常用的子类:
		|--Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。
			|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
		|--HashMap:内部结构式哈希表,不是同步的。允许null作为键,null作为值。
		|--TreeMap:内部结构式二叉树,不是同步的。可以对Map结合中的键进行排序。

		hashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。

		使用LinkedHashMap则是跟原来存入的顺序是一致的。
	————————————————————————————————————————————————————————————————————
	/**
	 * 需求:统计输入的字符串,如 "abcaab"  以a(3)b(2)c(1)的形式输出
	 * 分析:        1 字符与字符个数属于对应关系,可用Map<String,Integer>
	 *                         2 输出字母是自然排序,所以考虑使用TreeMap
	 */
	package fmi1;

	import java.util.Scanner;
	import java.util.Set;
	import java.util.TreeMap;

	public class CharacterCount {

			public static void main(String[] args) {
					// TODO Auto-generated method stub
					//建立接收键盘输入的字符串
					System.out.println("请输入字符串:");
					String line = new Scanner(System.in).nextLine();
					//建立集合Map
					TreeMap<Character, Integer> tm = new TreeMap<Character,Integer>();
					//将输入字符串转成数组
					char[] chs = line.toCharArray();
					//遍历字符串,将字符存入集合Map,若字符key已存在,则value加1,否则,value = 1
					for(char ch:chs        ){
							//根据键获取集合的值,判断字符的个数
							Integer value = tm.get(ch);
							if(null == value){//没有对应键值对
									value = 1;
							}
							else
									value++;
							//将更新后的键值关系存至Map
							tm.put(ch, value);
					}
					//遍历Map,输出键值对
					StringBuilder sb = new StringBuilder("");
					Set<Character> s = tm.keySet();
					for(Character ch:s){
							sb.append(ch).append("(").append(tm.get(ch)).append(")");
					}
					System.out.println(sb.toString());
			}
	}
	————————————————————————————————————————————————————————————————————
9、Collections工具类
10、Arrays:集合框架的工具类,里面的方法都是静态的。
		重点:List asList(数组)将数组转成集合。
		好处:可以使用集合的方法操作数组。

	P.S.
		数组的长度是固定的,所以对于结合的增删方法是不可以使用的,否则,会发生
			UnsupportedOperationException。

	数组转集合,用asList方法。
		如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
		如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。

	集合转数组
		使用的就是Collection接口中的toArray方法。
	
	集合转成数组,可以对集合中的元素操作的方法进行限定,不允许对其进行增删。
	toArray方法需要传入一个指定类型的数组。
	
	长度该如何定义呢?
	如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组。
	如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为
	null。

	所以建议,最后长度就指定为,集合的size。
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值