黑马程序员-集合学习笔记

------- android培训java培训、期待与您交流! ----------

----------------------------------------集合概念----------------------------------------

对象数组:Student[] stuArray = new Student[120];

  1.定义了一个120个长度的Student数组;

  2.数组的每个元素存储的是一个:Student对象的引用;

  3.此时,没有任何的Student对象产生;

  4.由于数组是引用类型的数组,所以每个元素都被初始化为:null

对象数组的弊端:

  1.一旦确定长度后,其长度就不能再更改了;这对我们程序员使用起来非常的不方便;

  2.数组定义时需要指定数据类型,那么就只能存储这个类型的数据;

针对数组的弊端:Java为我们程序员提供了一种新的工具(集合)

  1.集合的作用:就是用来装"对象的引用";

  2.这些集合就类似于"仓库",我们可以将它看做是一个:可以存储无限数量的引用的一个大仓库

    我们程序员使用时,只需要往里面增、删、改、查元素,其它的操作我们不需要管。

存储Student对象,使用数组,一旦定义长度,之后就不能改变;如果我们使用"集合"存储,我们就不用关心长度的问题;

集合结构图

----------------------------------------Collection的基本方法和批量方法----------------------------------------

基本方法:

  注意:如果大家在方法的形参或返回值类型中看到E字母,可以把它当做:Object

  boolean add(Object e):将参数e添加到集合

  boolean remove(Object o):将参数o从集合中移除

  void clear():清空集合

  boolean contains(Object o):基于equals()进行判断;

  boolean isEmpty():判断集合是否为空

  int size():集合中元素的数量;

public class Demo {
	public static void main(String[] args) {
		//1.定义集合对象
		Collection col = new ArrayList();//多态:可存储重复元素
		Collection col2 = new HashSet();//不能存储重复元素;
		
		//2.向仓库中添加元素
		System.out.println(col.add("孙悟空"));
		System.out.println(col.add("猪八戒"));
		System.out.println(col.add("沙师弟"));
		System.out.println(col.add("唐僧"));
		System.out.println(col.add("唐僧"));
		
		System.out.println("---------------------------");
		System.out.println(col2.add("孙悟空"));
		System.out.println(col2.add("猪八戒"));
		System.out.println(col2.add("孙悟空"));
		
		System.out.println("集合元素:" + col);
		//3.移除元素
		System.out.println("删除元素:唐僧: " + col.remove("唐僧"));
		System.out.println("删除元素:白骨精:" + col.remove("白骨精"));
		System.out.println("集合元素:" + col);
		
		//4.void clear()
	//	col.clear();
	//	System.out.println("清空集合后:" + col);
		
		//5.boolean contains(Object o)
		System.out.println("是否包含:白骨精:" + col.contains("白骨精"));
		System.out.println("是否包含:孙悟空:" + col.contains("孙悟空"));
		
		//6.boolean isEmpty()
	//	col.clear();
		System.out.println("集合是否为空:" + col.isEmpty());
		
		//7.int size():
		System.out.println("集合中元素的数量:" + col.size());
		
	}
}

批量操作元素的方法:

  boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合

  boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操

  boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true

  boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。

public class Demo {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		c1.add("孙悟空");
		c1.add("猪八戒");
		c1.add("唐三藏");
		
		Collection c2 = new ArrayList();
		c2.add("白骨精");
		c2.add("蜘蛛精");
		c2.add("狐狸精");
		
		//将集合c2中的所有元素,一次性全部添加到c1中
		/*c1.addAll(c2);
		System.out.println("c1.size : " + c1.size());//6
		System.out.println("c2.size : " + c2.size());//3
		System.out.println("c1 : " + c1);
		System.out.println("c2 : " + c2);
		*/
		//移除c1中c2的所有元素
		/*c1.removeAll(c2);
		System.out.println("c1 : " + c1);
		System.out.println("c2 : " + c2);*/
		
		//c1中是否包含c2
	//	System.out.println(c1.containsAll(c2));
		
		System.out.println(c1.retainAll(c2));
		System.out.println("c1 : " + c1);
		System.out.println("c2 : " + c2);	
	}
}

Collection类型的集合,有两种基本的遍历方法:

  1.Object[] toArray()方法:

  2.迭代器:Iterator iterator();

  Iterator(接口):

  boolean hasNext():  如果仍有元素可以迭代,则返回 true。 

  Object next() :返回迭代的下一个元素。 

public class Demo {
	public static void main(String[] args) {
		Collection c1 = new ArrayList();
		c1.add("孙悟空");
		c1.add("猪八戒");
		c1.add("唐三藏");
		
		//遍历方式一:
		Object[] objArray = c1.toArray();
		for(int i = 0;i < objArray.length ; i++){
			System.out.println(objArray[i]);
		}
		System.out.println("---------------------------");
		//遍历方式二:迭代器
		Iterator it = c1.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}
}

 Collection(接口):

      |--List(接口):1.可以存储重复的;2.有序的(取出时的顺序同存入时一致)

特有方法:

    void add(int index,E element):将element添加到index位置;原index位置上元素依次后移;

    E remove(int index):移除index位置上的元素

    E get(int index):获取index位置上的元素

    E set(int index,E element):将element替换原index位置上的元素;

 特有遍历方式:

 方式一: ListIterator listIterator():获取List的迭代器。ListIterator是Iterator的子接口;

  跟Iterator的不同:

  1.Iterator:单项的迭代器。只能向下遍历;

  2.ListIterator:双向的迭代器,可以向上遍历;注意:在向上遍历前,一定要先向下遍历;

 方式二:结合使用Collection的size()和List接口的get()方法,使用for循环进行遍历;

public class Demo {
	public static void main(String[] args) {
		//1.实例化一个集合
		List list = new ArrayList();
		list.add("张三");
		list.add("李四");
		list.add("王五");
		Iterator it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
		//在"李四"之前,插入一个"赵七"
		list.add(1,"赵七");
		System.out.println("list :" + list);
		
		//移除"赵七"
		list.remove(1);
		System.out.println("移除赵七后:" + list);
		
		//获取王五
		System.out.println("获取王五:" + list.get(2));
		
		//将王五替换为赵七
		list.set(2, "赵七");
		System.out.println("将王五替换为赵七后:" + list);
		
		//结合Collection的size()和List的get()方法,可以遍历List类型的集合:
		for(int i = 0; i < list.size() ; i++){
			System.out.println(list.get(i));
		}
		System.out.println("-----------------------");
		//获取一个ListIterator
		ListIterator listIt  = list.listIterator();
		System.out.println("先向下遍历:");
		while(listIt.hasNext()){
			System.out.println(listIt.next());
		}
		System.out.println("向上遍历:");
		while(listIt.hasPrevious()){
			System.out.println(listIt.previous());
		}
		
		System.out.println("=====================");		
	}
}

并发修改异常:

  1.Iterator:remove()方法不会触发并发修改异常;

  2.ListIterator:

       remove()方法不会触发并发修改异常;

       set()方法不会触发并发修改异常;

       add()方法不会触发并发修改异常;

  3.当使用迭代器遍历元素时,通过List的对象去修改元素内容时,

     会引发并发修改异常:ConcurrentModificationException

解决:使用迭代器遍历,如果要修改集合,就要通过迭代器去修改。不要通过List对象修改;

----------------------------------------各数据结构特点----------------------------------------

1.栈:先进后出

2.队列:先进先出

3.数组:随机获取元素快,增、删慢;

4.链表:查询慢,增、删非常快;


 

 

----------------------------------------List接口的三个子类----------------------------------------

Collection(接口)

  |--List(接口):1.有序的;2.可以存储重复值

       |--ArrayList(类):1.数组实现;2.不是同步的(不保证线程安全),效率高; 

       |--Vector(类):1.数组实现;2.同步的(线程安全的),效率低

         特有方法:

                 public void addElement(E obj):添加一个元素;(相当于Collection的add()方法)

                 public E elementAt(int index):获取index位置上的元素;(相当于List的get()方法)

       |--LinkedList(类):1.链表实现。2.非同步的(线程不安全的),效率高;

          特有方法:

                  public void addFirst(E e)及addLast(E e):

                  public E getFirst()及getLast()

                  public E removeFirst()及public E removeLast()

  |--Set(接口):1.无序的;2.不能存储重复值

public class Demo {
	public static void main(String[] args) {
		// 1.实例化一个Vector
		Vector vec = new Vector();
		System.out.println(vec.capacity());
		// 2.填充集合
		vec.add(new Student("刘德华", 20));
		vec.add(new Student("张学友", 22));
		vec.addElement(new Student("章子怡", 18));
		vec.addElement(new Student("汪峰", 80));

		// 3.遍历
		for (int i = 0; i < vec.size(); i++) {
			Student stu = (Student) vec.elementAt(i);
			System.out.println(stu.name + "," + stu.age);
		}
	}
}

//学生类
public class Student {
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}
public class Demo {
	public static void main(String[] args) {
		LinkedList list = new LinkedList();
		/*list.add("aaa");
		list.add("bbb");
		list.add("ccc");*/
		
		list.addFirst("aaa");
		list.addFirst("bbb");
		list.addFirst("ccc");
		
		for(int i = 0;i < list.size() ; i++){
		//	System.out.println(list.get(i));
			System.out.println(list.getLast());
			list.removeLast();
			i--;
		}
	}
}

 Arrays类的_asList方法_将数组转换为集合:

public class Demo {
	public static void main(String[] args) {
		List<String> strList = Arrays.asList("张三", "李四", "王五", "周六");
		List<Integer> intList = Arrays.asList(10, 2, 34, 2, 5, 4, 34, 2);

		int[] arr = { 1, 2, 3, 4, 5 };
		
		List<int[]>array = Arrays.asList(arr);//0x2233
		
		
		for (int[] o : array) {
			for (int i = 0; i < o.length; i++) {
				System.out.println(o[i]);
			}
	}
}

 集合嵌套之ArrayList嵌套ArrayList

  一个班的学员:刘德华,  张学友,  郭富城,黎明;另一个班的学员:章子怡, 范冰冰, 李宇春, 罗玉凤  

  将上述两个集合添加到一个大集合中;

public class Demo {
	public static void main(String[] args) {
		List<String> class1List = new ArrayList<>();
		class1List.add("刘德华");
		class1List.add("张学友");
		class1List.add("郭富城");
		class1List.add("黎明");

		List<String> class2List = new ArrayList<>();
		class2List.add("章子怡");
		class2List.add("范冰冰");
		class2List.add("李宇春");
		class2List.add("罗玉凤");

		List<List<String>> list = new ArrayList<>();
		list.add(class1List);
		list.add(class2List);

		for (List<String> classList : list) {
			for (String s : classList) {
				System.out.println(s);
			}
		}
	}
}

Collection(接口)

  |--Set(接口):1.无序的;2.不能存储重复值

      |--HashSet(类):哈希表结构;综合了数组和链表的优点了。查询快;增、删快;

           1.重复性验证:第一步:哈希值;第二步:equals():

           使用HashSet存储自定义对象

              1.需要判断出两个对象中的属性值是否完全一样,需要重写hashCode()和equals();

              2.怎么重写? 鼠标-->右键-->source-->Generate hashCode() and equals()

      |--LinkedHashSet(类):链表和哈希表结构:

           1.有序的;(由链表保证顺序)

            2.不存储重复值;(由哈希表保证唯一):hashCode-->equals()

      |--TreeSet(类):树结构;特点:对元素进行排序;

           1.树结构存储;验证唯一性:如果"比较器"的"比较的方法"返回0,则认为是相同对象;

           2.树结构的特点:对元素进行排序:

                 1).自然排序:

                       1.存储的对象,必须实现:Comparable接口

                       2.重写compareTo()方法;

                  2).比较器排序:

                        1.存储的对象无需实现任何接口;

                        2.需要自定义一个比较器,实现:Comparator接口,重写compare()方法;

                        3.构造TreeSet时,为其传递一个"比较器对象"给构造方法;

                        说明:第2,3步,我们一般使用"匿名内部类"实现;

使用HashSet(哈希表结构)存储自定义对象

  1.需要判断出两个对象中的属性值是否完全一样,需要重写hashCode()和equals();

public class Student {
	String name;
	int age;

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

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

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
public class Demo {
	public static void main(String[] args) {
		Set<Student> stuSet = new HashSet<>();
		stuSet.add(new Student("张三", 20));
		stuSet.add(new Student("李四", 22));
		stuSet.add(new Student("王五", 24));

		stuSet.add(new Student("王五", 24));//存不进去,set不存重复值

		for (Student stu : stuSet) {
			System.out.println(stu.name + "---" + stu.age);
		}
	}
}

 LinkedHashSet:链表和哈希表结构:

1.有序的;(由链表保证顺序)

2.不存储重复值;(由哈希表保证唯一):hashCode-->equals()

public class Demo {
	public static void main(String[] args) {
		LinkedHashSet<String> set = new LinkedHashSet<>();
		// 添加元素
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		set.add("ddd");

		set.add("ddd");// 不存储重复值;(由哈希表保证唯一)
		// 遍历集合
		for (String s : set) {
			System.out.println(s);
		}
	}
}

 TreeSet:树结构:特点:对元素进行排序;排序的方式:

一:自然排序;

二:比较器排序;

public class Demo {
	public static void main(String[] args) {
		TreeSet<Integer> tree1 = new TreeSet<>();
		// 存无序
		tree1.add(20);
		tree1.add(18);
		tree1.add(23);
		tree1.add(22);
		tree1.add(17);
		tree1.add(24);
		tree1.add(19);
		tree1.add(18);
		tree1.add(24);
		// 取有序
		for (Integer i : tree1) {
			System.out.print(i+",");
         }		
}

 TreeSet类_比较器排序:

public class Student{
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}
public class Demo {
	public static void main(String[] args) {
		TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				// 1.先比较年龄
				int n1 = o1.age - o2.age;
				// 2.再判断姓名
				int n2 = (n1 == 0 ? o1.name.compareTo(o2.name) : n1);
				return n2;
			}
		});

		set.add(new Student("张三", 20));
		set.add(new Student("李四", 19));
		set.add(new Student("赵七", 28));

		set.add(new Student("赵七", 28));// 重复的元素;

		for (Student stu : set) {
			System.out.println(stu.name + "--" + stu.age);
		}
	}
}

 --------------------------------Map接口------------------------------------

Map(接口):双列集合:键、值对存储  注意:Map的数据结构都是引用在"键"上

  |--HashMap:哈希表

  |--LinkedHashMap:哈希表和链表结构;有序的双列集合

  |--TreeMap:树结构

     TreeMap需要对"键"进行排序,排序的方式:

  1.自然排序:

   1).作为"键"的对象,一定要实现:Comparable接口

   2).重写compreTo()方法;

  2.比较器排序:

   1).自定义比较器对象,要实现:Comparator接口;

   2).重写compare()方法;

   3).在实例化TreeMap时,将自定义的比较器对象传入TreeMap的构造方法;

Map集合的基本功能:

  1.put(K key ,V value):添加元素;

  2.clear():清空集合

  3.remove(Object key):移除键key

  4.containsKey(Object key):判断键key在集合中是否存在;

  5.boolean containsValue(Object value):判断值value,在集合中是否存在;

  5.isEmpty():判断集合是否为空;

  注意:关于put()方法的返回值:

  1.如果put()进去一个未曾添加的一个新键值对,那么返回null;

  2.如果put()进去一个已经存在的键,那么用"新值"替换"原值";

Map集合的获取功能测试

  V get(Object key):用一个key查找对应的值;

  Set<K> keySet():返回所有键的Set集合;

  Collection<V> values():获取所有value的集合;

  Set<Map.Entry<K,V>> entrySet():获取所有"键值对对象";

  Map的遍历方式只有两种:

  1.keySet:先获取所有键的集合,然后遍历键的集合,根据每个键去获取值;

  2.entrySet:获取所有的"键值对对象"的集合,然后遍历;

public class Demo {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		System.out.println(map.put("it001", "刘德华"));
		System.out.println(map.put("it002", "张学友"));
		System.out.println(map.put("it003", "章子怡"));
		System.out.println(map.put("it004", "撒贝宁"));

		System.out.println(map.put("it004", "汪峰"));

		// 清空集合
		// map.clear();
		// 移除it004
		// System.out.println("移除it005结果:" + map.remove("it005"));
		// System.out.println("移除it004结果:" + map.remove("it004"));

		// 判断键it004是否存在
		System.out.println("判断键it004是否存在:" + map.containsKey("it004"));
		System.out.println("判断键it005是否存在:" + map.containsKey("it005"));
		System.out.println("判断章子怡是否存在:" + map.containsValue("章子怡"));
		System.out.println("判断汪峰是否存在:" + map.containsValue("汪峰"));
		System.out.println("集合是否为空: " + map.isEmpty());
		System.out.println(map);

	}
}
public class Demo {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		map.put("it001", "刘德华");
		map.put("it002", "张学友");
		map.put("it003", "章子怡");
		map.put("it004", "撒贝宁");

		// System.out.println("获取it004对应的值:" + map.get("it004"));

		// 遍历Map集合的一种方式:
		Set<String> keys = map.keySet();
		for (String key : keys) {
			System.out.println(key + "----" + map.get(key));
		}
		System.out.println("------------Map.Entry遍历--------------");
		// 遍历Map集合的第二种方式:
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		for (Map.Entry<String, String> en : entrySet) {
			System.out.println(en.getKey() + "---" + en.getValue());
		}
	}
}

 LinkedHashMap的概述和使用:

public class Demo {
	public static void main(String[] args) {
		LinkedHashMap<String, String> map = new LinkedHashMap<>();
		map.put("it001", "刘德华");
		map.put("it002", "张学友");
		map.put("it003", "黎明");
		map.put("it004", "郭富城");

		// 遍历
		// 1.keySet():
		// 2.entrySet():
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + "--" + map.get(key));
		}
	}

 TreeMap_键是Student值是String的案例:

public class Student {
	String name;
	int age;

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}
public class Demo {
	public static void main(String[] args) {
		TreeMap<Student, String> map = new TreeMap<>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				// 1.先按年龄排
				int n1 = o1.age - o2.age;
				// 2.如果年龄相同,按姓名排
				int n2 = (n1 == 0 ? o1.name.compareTo(o2.name) : n1);
				return n2;
			}
		});
		map.put(new Student("张三", 20), "it001");
		map.put(new Student("李四", 18), "it003");
		map.put(new Student("王五", 22), "it002");
		map.put(new Student("周六", 17), "it004");

		Set<Student> keySet = map.keySet();
		for (Student stu : keySet) {
			System.out.println(stu.name + "," + stu.age + "---" + map.get(stu));
		}
	}
}

 java.util.Collections(工具类):对集合操作的工具类;  

  public static <T> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。-->compareTo()

  public static <T> int binarySearch(List<?> list,T key):在集合list中查找key:要先排序;

  public static <T> T max(Collection<?> coll):获取集合中的最大元素;

  public static void reverse(List<?> list):反转集合内的所有元素;

  public static void shuffle(List<?> list):打乱集合中所有元素的顺序;

public class Demo {
	public static void main(String[] args) {
		List<String> arrayList = new ArrayList<>();
		arrayList.add("ccc");
		arrayList.add("bbb");
		arrayList.add("aaa");
		arrayList.add("ddd");

		System.out.println(arrayList);

		// 排序
		Collections.sort(arrayList);

		System.out.println(arrayList);

		// 查找元素"ddd"
		System.out.println("查找元素ddd: "
				+ Collections.binarySearch(arrayList, "ddd"));
		System.out.println("集合中的最大元素:" + Collections.max(arrayList));
		Collections.reverse(arrayList);
		System.out.println("反转集合内的元素:" + arrayList);
		Collections.shuffle(arrayList);
		System.out.println("打乱集合内的元素的顺序:" + arrayList);
	}
}

猜你喜欢

转载自shuangxi-zhu.iteye.com/blog/2247080