java高级部分(四)

Map集合

 需求:有很多学生,学生有姓名,有学号,怎样根据学生的学号查找学生?

  之前学习的集合,可以将姓名,学号作为学生类的中两个成员变量,创建集合的时候存储这个类型

  关键只知道学生学号,通过学号找姓名

  Key   Value

  学号1 姓名1

  学号2 姓名2

  学号3 姓名3

  学号1(重复的键) 姓名4

  Java针对这种情况采取了一种技术----->Map集合 ,键值的映射关系的一种集合(接口)

  将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

  Map<K,V> ,Map集合中,只针对键有效,跟值无关

  Map接口的子实现类:

HashMapTreeMap

  Map接口的功能:

 添加功能:

   V put (  K key,V value ) :将指定的值和键关联起来

   如果当前的这个键是一次存储,则返回值null

   如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉!

  获取功能

   Set<Map.Entry<K,V>> entrySet() :Map集合的遍历有关系(键值对对象)

   Set<K> keySet():获取映射关系中所有的键的集合

   int size()返回此映射中的键-值映射关系数

   删除功能

   void clear():删除所有映射关系

    Vremove(Object key)如果存在一个键的映射关系,则将其从此映射中移除

    判断功能:

     boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true

     boolean containsValue(Object value):映射关系中是否包含指定的值

     boolean isEmpty():判断映射关系是否为空

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

public class MapDemo1 {

	public static void main(String[] args) {
		Map<String,String> m=new HashMap<>();
		System.out.println(m.put("23", "zhangsan"));
		//添加元素
				m.put("高圆圆", "赵又廷") ;
				m.put("周杰伦", "昆凌") ;
				m.put("黄晓明", "babay") ;
				m.put("文章", "马伊琍") ;
				System.out.println(m.containsKey("高圆圆"));
				System.out.println(m.containsKey("赵又廷"));
				System.out.println(m.containsKey("杨过"));
				System.out.println(m.containsValue("马伊琍"));
				System.out.println(m.isEmpty());
				System.out.println(m.remove("周杰伦"));
				System.out.println(m.size());
				System.out.println(m);
	}
}


 Map集合的遍历(一)

  Set<K> keySet():获取映射关系中所有的键的集合

  V get(Object key):通过键找值

  转换法:

    这种遍历方式实际开发中经常用的...

  思路:   

   1)获取所有的键的集合

   2)通过键找它对应的值

   3)遍历即可

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

public class MapDemo2 {
	public static void main(String[] args) {
		Map<String, String> m=new HashMap();
		m.put("杨过", "小龙女") ;
		m.put("郭靖", "黄蓉") ;
		m.put("陈旋风", "梅超风") ;
		m.put("高圆圆", "赵又廷") ;
		
		Set<String> set=m.keySet();
		for(String s:set) {
			String ss=m.get(s);
			System.out.println(s+"="+ss);
		}		
	}
}

Map集合的遍历 (二)

Set<Map.Entry<K,V>> entrySet() :Map集合的遍历有关系(键值对对象)

  转发法

1)获取所有的结婚证 

2)通过结婚证分别找对应的丈夫和妻子 

3)遍历输出

  思路

1)获取所有的键值对象entrySet()

2) K getKey() v getValue(),获取键值对对象中的每个键和每个值

3)遍历

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

public class MapDemo3 {
	public static void main(String[] args) {
		Map<String, String> m=new HashMap();
		m.put("杨过", "小龙女");
		m.put("郭靖", "黄蓉");
		m.put("陈旋风", "梅超风");
		m.put("高圆圆", "赵又廷");
		
		Set<Map.Entry<String, String>> entry=m.entrySet();
		for(Map.Entry<String, String> kv:entry) {
			String key=kv.getKey();
			String value=kv.getValue();
			System.out.println(key+"="+value);
		}
	}
}

                                        HashMap

HashMap集合本身基于哈希表

  它可以保证键的唯一性(Map都是针对键有效)

  HashMap<String,String>

 HashMap底层哈希表

  哈希表:依赖于两个方法  hashCode() ,equals()方法

 线程安全的类:
  StringBuffer :字符串缓冲区
  Vector  :List集合
  Hashtable  :Map集合的

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

public class HashMapDemo1 {
	public static void main(String[] args) {
		HashMap<String, String> map=new HashMap();
		
		map.put("it001", "马云") ;
		map.put("it003", "马化腾") ;
		map.put("it004", "乔布斯") ;
		map.put("it001", "裘伯君"); 
		map.put("it005", "比尔盖茨");
		
		Set<String> set = map.keySet();
		for(String s:set) {
			System.out.println(s+"---"+map.get(s));
		}
	}
}

                                  LinkedHashMap

LinkedHashMap<K,V> :是Map接口基于哈希表和链接列表实现的

 哈希表保证键的唯一性

 链接列表保证元素有序性(存储和取出一致)

import java.util.LinkedHashMap;
import java.util.Set;

public class LInkedHashDemo1 {
	public static void main(String[] args) {
		LinkedHashMap<String, String> map=new LinkedHashMap();
		map.put("it001", "hello");
		map.put("it002", "mysql");
		map.put("it003", "world");
		map.put("it004", "javaweb");
		map.put("it001", "javaee");
		
		Set<String> set = map.keySet();
		for(String s:set) {
		
			String ss=map.get(s);
			System.out.println(s+"---"+ss);
		}
	}
}

                                         TreeMap

TreeMap基于红黑树结构的Map接口的实现

 TreeMap存储自定义类型

 TreeMap<Student,String>

 

public class TreeMapDemo2 {
	public static void main(String[] args) {
		TreeMap<Student, String> tm=new TreeMap(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
			
				int num=s1.getAge()-s2.getAge();
				return num;
			}
		});


需求:
  字符串:比如: aaaaabbbbcccddddee   ,最终控制台要出现的结果:a(5)b(4)c(3)d(3)e(2)
 
 思路:
  1)改进:键盘录入一个字符串
  2)创建一个HashMap集合key:Character,Value:Integer
  3)将录入的字符串转换成字符数组
  4)遍历可以获取每一个字符
 
  5)将元素添加到对应的HashMap集合中
  使用的put(key,value): 通过判断值是否null ,如果是null表示第一次存储
  集合对象.put(ch,1) ;
  否则,不是null
  Integer那个值++;
  集合对象.put(ch,变量Integer值)  ;
 

  6)遍历HashMap集合即可

import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;

public class 统计字符个数 {
	@SuppressWarnings("unused")
	public static void main(String[] args) {
		HashMap<Character, Integer> map=new HashMap();
		Scanner in =new Scanner(System.in);
		System.out.println("请输入您要统计的字符串:");
		String str=in.next();
		char[] ch=str.toCharArray();
		for(Character c:ch) {
			Integer i=map.get(c);
			if(i==null) {
				map.put(c, 1);
			}else {
				i++;
				map.put(c, i);
				
			}
		}
		Set<Character> set = map.keySet();
		StringBuilder sb=new StringBuilder();
		for(Character ccc:set) {
			Integer i=map.get(ccc);
			sb.append(ccc).append("(").append(i).append(")");
		}
		String s=new String(sb);
		System.out.println(s);
	}
}

                                     

                                          Collections


Collection和Collections的区别:
  Collection:顶层次单列集合的根接口,它是一个集合,是一个接口
  Collections:是针对集合操作的工具类,有一些功能:随机置换,集合里面的二分查找,将集合的元素进行反转
 
Collections常用方法:

  public static <T> int binarySearch(List<T> list, T key) 集合的二分查找

  static  T max(Collection coll):获取集合中的最大值

  public static void reverse(List<?> list):将集合中的元素顺序反转

  public static void shuffle(List<?> list):将集合中的元素打乱

  public static void sort(List<T> list):排序

Collections.sort(list, 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;
			}	
		});

                    set集合

 Set集合和List集合的区别?

  Set集合:不允许元素重复,唯一的(元素可以为null) ,不能保证迭代的顺序恒久不变(底层是哈希表和hascode)

  无序(存储和取出不一致)

  List集合:允许元素重复,并且存储特点:有序性(存储和取出一致)


用Set集合存储元素并遍历

发现Set集合存储元素的时候,可以保证元素的唯一性,原因什么?

  看源码:

  HashSet集合的add方法底层依赖于双列集合HashMap,它依赖于两个方法,HashCode()方法和equals()方法

   先比较字符串的HashCode()码值一样,再比较equals()方法

  如果hasCode码值一样,还要比较内容是否相同,由于存储String,重写了equals()方法

  String本身重写了equals方法,所以不需要再重写了!

  

Set集合存储自定义对象遍历

  现在是自定义的类,HashSet集合的add()方法本身依赖于hashCode()equals()方法

  Student类中并没重写这两个方法,

  解决办法:重写这两个方法


如果在开发中,要保证元素的唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合

 LinkedHashSet集合:

  底层是一种链接列表哈希表组成

  可以保证元素的唯一性,是由哈希表决定的(hashCode()equals())

  可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定

import java.util.LinkedHashSet;

public class LinkedHashSetDemo1 {
	public static void main(String[] args) {
		LinkedHashSet<String> link=new LinkedHashSet();
		link.add("hello") ;
		link.add("java") ;
		link.add("world") ;
		link.add("world") ;
		link.add("world") ;
		link.add("java") ;
		
		for(String s:link) {
			System.out.println( s);
		}		
	}
}

  如果开发中要使用集合排序的问题,使用TreeSet集合(红黑树结构)

  TreeSet:

   可以保证元素唯一并且元素排序(Integer类型的元素自然升序)

   1)自然排序

   2)选择器排序

对于自定义的类型,要实现自然排序,自定义的类型必须实现Comparable接口中的方法,compareTo() :比较方法

TreeSet集合模拟情况下是通过自然顺序对集合中的元素排序


  TreeSet集合存储以下元素:20,23,22,18,17,19,24..

import java.util.TreeSet;

public class TreeSetDemo1 {

	public static void main(String[] args) {
		TreeSet<Integer> ts=new TreeSet();
		ts.add(20) ;		//add()方法底层的源码是一个Map接口实例
		ts.add(22) ;
		ts.add(18) ;
		ts.add(23) ;
		ts.add(24) ;
		ts.add(17) ;
		ts.add(19) ;
		ts.add(18) ;
		ts.add(24) ;
		
		for(Integer i:ts) {
			System.out.println(i);
		}
	}
}

需求:使用TreeSet集合存储自定义对象(Student类型),并遍历!

   如何排序?

   按照学生的年龄从小到大进行排序 (主要条件)

  唯一性:

   如果成员变量的值一样认为是同一个对象

import java.util.Comparator;

//自定义类,该类实现Comparator保证集合中的元素进行比较器排序

public class MyComparator implements Comparator<Student> {
 
@Override

public int compare(Student s1, Student s2) {

/

  自然排序:Comparable 里面compareTo(Student s)

 this---->s1

 s---s

 /

//return 0;

//按照姓名长度进行比较

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 ;
}
}
 


TreeSet集合的构造方式不同,使用的排序也不同

  自然排序:自定义的类实现Compareable接口,然后创建TreeSet对象,通过无参构造形式创建对象

  比较器排序 :public TreeSet(Comparator<E> comparator)

  两种方式:

  1)自定义一个类,该类实现Comparator接口,重写Comparator接口中的compare()方法

  2)直接使用接口匿名内部类的方式实现

 TreeSet集合保证元素唯一,是看返回值是否为0

比较器排序:

TreeSet<Student4> ts=new TreeSet(new Comparator<Student4>() {

			@Override
			public int compare(Student4 s1, Student4 s2) {
				int num1=s1.getName().length()-s2.getName().length();
				int num2=num1==0?s1.getName().compareTo(s2.getName()):num1;
				int num3=num2==0?s1.getAge()-s2.getAge():num2;
				return num3;
				
			}
			
		});


猜你喜欢

转载自blog.csdn.net/m0_37167369/article/details/80246054