Java学习11-集合2

本文深入探讨Java集合框架的基本概念、使用方法及其在实际编程中的应用案例,包括Map、Set、List、TreeMap、TreeSet等核心组件的特性与操作,以及如何利用Collections工具类对集合进行排序、查找等高级操作。



1.Map集合
该集合存储键值对。一对一对往里存。而且要保证 键的唯一性
 1,添加。
  put(K key, V value)
  putAll(Map<? extends K,? extends V> m)
 2,删除。
  clear()
  remove(Object key)
 3,判断。
  containsValue(Object value)
  containsKey(Object key)
  isEmpty()
 4,获取。
  get(Object key)
  size()
  values()
  entrySet()
  keySet()
Map
 |--Hashtable:底层是哈希表数据结构, 不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
 |--HashMap:底层是哈希表数据结构, 允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
 |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像。
其实大家, Set底层就是使用了Map集合
map.put()会返回这个键原来的的值。

map集合的两种取出方式:
1,Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。
 所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
 Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。
2,Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,
    而这个关系的数据类型就是:Map.Entry
    Entry其实就是Map中的一个static内部接口。
    为什么要定义在内部呢?
    因为只有有了Map集合,有了键值对,才会有键值的映射关系。
    关系属于Map集合中的一个内部事物。
    而且该事物在直接访问Map集合中的元素。
<p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span style="background-color: inherit; font-family: 宋体;">练习:</span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span lang="EN-US" style="background-color: inherit;">"sdfgzxcvasdfxcvdf"</span><span style="background-color: inherit; font-family: 宋体;">获取该字符串中的字母出现的次数。</span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span lang="EN-US" style="background-color: inherit;"><span style="background-color: inherit;"> </span></span></p><p style="margin-top: 5px; margin-bottom: 5px; font-family: 微软雅黑; font-size: 14px; line-height: 21px;"><span style="background-color: inherit; font-family: 宋体;">希望打印结果:</span><span lang="EN-US" style="background-color: inherit;">a(1)c(2).....</span></p>package nuddles.j2seDemo;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapDemo {

	 * @param args
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Map<String,String> map = new HashMap<String, String>();
		map.put("11", "22");
		System.out.println(map.put("11","33"));
//		返回原值“22”;
		map.put("33", "44");
		map.put("34", "44");
		map.put("35", "44");
		map.put("36", "44");
		map.put("39", "44");
		Set<String> set = map.keySet();
//		用keySet取出
		for (String string : set) {
			System.out.println(string+","+map.get(string));
		}
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		for(Map.Entry<String, String> mapEntry:entrySet){
//			用entrySet取出
			System.out.println(mapEntry.getKey()+","+mapEntry.getValue());
		}
	}

}
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
1,描述学生。
2,定义map容器。将学生作为键,地址作为值。存入。
3,获取map集合中的元素。

import java.util.*;
class Student implements Comparable<Student>{
	// 实现Comparable接口
	private String name;
	int age;
	Student(String name, int age){
		this.name = name;
		this.age = age;
	}
	public int compareTo(Student s){
		// 重写此方法
		if (this.age==s.age) {
			return this.name.compareTo(s.name);
		}else {
			return new Integer(this.age).compareTo(s.age);
		}
	}
	public int hashCode(){
		return this.name.hashCode()+this.age;
	}
	public boolean equals(Object obj){
		if (! (obj instanceof Student)) {
			throw new ClassCastException();
		}
		Student ss = (Student)obj;
		return this.name.equals(ss.name)&&this.age == ss.age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public String toString()
	{
		return name+":"+age;
	}
}

public class MapTest1 {
	public static void main(String[] args) {
		Map<Student,String> map = new HashMap<Student,String>();
		map.put(new Student("nuddles01",23),"jiangxi");
		map.put(new Student("nuddles02",23),"jiangxi");
		map.put(new Student("nuddles03",23),"jiangxi");
		map.put(new Student("nuddles01",23),"jiangxi");
		sop(map);
		Set<Map.Entry<Student,String>> me = map.entrySet();
		for(Map.Entry<Student,String> e:me){
			// 高级For循环取出
			Student stu = e.getKey();
			String adr = e.getValue();
			sop(stu.toString()+","+adr);		
		}
		Set<Student> set = map.keySet();
		for(Student stu:set){
			String adr = map.get(stu);
			sop(stu.toString()+","+adr);
		}
		/*Set<Map.Entry<Student,String>> me = map.entrySet();
		Iterator<Map.Entry<Student,String>>  it = me.iterator();
		while (it.hasNext()) {
			Map.Entry<Student,String> e = it.next();
			Student stu = e.getKey();
			String adr = e.getValue();
			sop(stu.toString()+","+adr);
		}

		Set<Student> keyset = map.keySet();*/

		/*Iterator<Student> itr = keyset.iterator();
		while (itr.hasNext()) {
			Student stu = itr.next();
			sop(stu.toString()+","+map.get(stu));
		}*/
	
	}
	public static void sop(Object obj){
		System.out.println(obj);
	}
	
}

练习:

"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。

 希望打印结果:a(1)c(2).....


/*
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
 
希望打印结果:a(1)c(2).....
 
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
 
注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。
什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。
 
思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
 3,遍历字符数组。
         将每一个字母作为键去查map集合。
         如果返回null,将该字母和1存入到map集合中。
         如果返回不是null,说明该字母在map集合已经存在并有对应次数。
         那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。
 
4,将map集合中的数据变成指定的字符串形式返回。
 
*/
package nuddles.j2seDemo;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String string =  "sdfgzxcvasdfxcvdf";
		charCount(string);
	}

	public static void charCount(String string){
		Map<Character,Integer> map = new HashMap<Character,	Integer>();
		int count;
		char[] cha = string.toCharArray();
		for (char c : cha) {
//			if (!(c>='a'&&c<='z'|| c>='A'&&c<='Z')) {
				if (!(new Character(c).toString().matches("[a-zA-Z]"))) {
//					用正则表达式来判断是不是字母
				continue;
			}
			Integer value = map.get(c);
			if (value != null ) {
//				如果map中已经有这个字母,则相应值加1
				count = value;
				count++;
				map.put(c, count);
			}else {
//				没有则初始化为1
				map.put(c, 1);
			}
		}
		Set<Character> set = map.keySet();
		StringBuilder sb = new StringBuilder();
//		用StringBuilder来汇总
		for (char c : set) {
			sb.append(c+"("+map.get(c)+")");
		}
		System.out.println(sb.toString());
	}
}

f(3)v(2)g(1)d(3)s(2)c(2)a(1)z(1)x(2)

2.集合框架的工具类。
Collections:集合框架的工具类。里面定义的都是静态方法。
Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
  它有两个常用的子接口,
  List:对元素都有定义索引。有序的。可以重复元素。
  Set:不可以重复元素。无序。

Collections是集合框架中的一个工具类。该类中的方法都是静态的
  提供的方法中有可以对list集合进行排序,二分查找等方法。
  通常常用的集合都是线程不安全的。因为要提高效率。
  如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

Collections.sort(list);//list集合进行元素的自然顺序排序。

Collections.sort(list,new ComparatorByLen());//按指定的比较器方法排序。

class ComparatorByLen implements Comparator<String>{

public int compare(String s1,String s2)
{  int temp = s1.length()-s2.length(); 
   return temp==0
   s1.compareTo(s2):temp;
 }
}


Collections.max(list);//返回list中字典顺序最大的元素。

int index = Collections.binarySearch(list,"zz");//二分查找,返回角标。必须是有序的

Collections.fill();//可以将list集合中的所有元素替换成指定元素。

Collections.repalceAll(list,"要被替换的","替换的值");//可以将list集合中的指定元素替换成指定元素。

Collections.reverse(); 反转

Collections.reverseOrder(参数是比较器);//逆向反转排序。倒序。。 

Collections.shuffle(list);//随机对list中的元素进行位置的置换。 

将非同步集合转成同步集合的方法:
Collections中的  XXX synchronizedXXX(XXX);
List synchronizedList(list);
 Map synchronizedMap(map) ;
原理:定义一个类,将集合所有的方法加同一把锁后返回。

import java.util.*;
import static java.util.Collections.*;
 
class CollectionsDemo {
         public static void main(String[] args) {
                   List<String> list = new ArrayList<String>();
                   list.add("aaa");
                   list.add("zzzz");
                   list.add("kkkl");
                   list.add("zzz");
                   sop(list);
                   sort(list,new StrLength());
                   sop(list);
                   sort(list,reverseOrder(new StrLength()));
                   sop(list);
                   sop(max(list,new StrLength()));
                   sop(binarySearch(list,"zzz"));
                   shuffle(list);
                   sop(list);
                   fill(list,"bbb");
                   sop(list);
 
         }
         public static void sop(Object obj){
                   System.out.println(obj);
         }
}
 
class StrLength implements Comparator<String>{
         public int compare(String s1,String s2){
                   if (s1.length()>s2.length()) {
                            return 1;
                   }else if (s1.length()<s2.length()) {
                            return -1;
                   }else {
                            return s1.compareTo(s2);
                   }
         }
}
Compiling CollectionsDemo.java.......  
-----------OUTPUT-----------  
[aaa, zzzz, kkkl, zzz]
[aaa, zzz, kkkl, zzzz]
[zzzz, kkkl, zzz, aaa]
zzzz
2
[aaa, zzzz, kkkl, zzz]
[bbb, bbb, bbb, bbb]
[Finished in 0.8s]

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

4.Arrays:用于操作数组的工具类。
里面都是静态方法。


asList:将数组变成list集合
把数组变成list集合有什么好处?
 可以使用集合的思想和方法来操作数组中的元素。

  注意:将数组变成集合,不可以使用集合的增删方法。
  因为数组的长度是固定。
  contains。
  get
  indexOf()
  subList();

  如果你增删。那么会反生UnsupportedOperationException,

如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
  如果数组中的元素都是基本数据类型, 那么会将该数组作为集合中的元素存在。
df
import java.util.*;
import static java.util.Arrays.*;
 
class ArraysDemo  {
         public static void main(String[] args) {
                   int[] arr = {3,4,24,5,6,3};
                   List al = asList(arr);
                   sop(al);
                   Integer[] arr2 = {3,4,24,5,6,3};
                   List al2 = asList(arr2);
                   sop(al2);
                   sop(al2.contains(3));
 
         }
         public static void sop(Object obj){
                   System.out.println(obj);
         }
}

Compiling ArraysDemo.java....... 
-----------OUTPUT----------- 
[[I@1db9742
[3, 4, 24, 5, 6, 3] 
true 
[Finished in 0.8s]

5.高级for循环

格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{
 
}

对集合进行遍历。
只能获取集合元素。但是不能对集合进行操作。

迭代器除了遍历, 还可以进行remove集合中元素的动作。
如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作

传统for和高级for有什么区别呢?
高级for有一个局限性。必须有被遍历的目标。
建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值