03集合框架

集合框架

1.Collection集合

在这里插入图片描述

A.数组(存放任意类型,长度固定)
B.集合(存放对象类型,长度可变)
单列集合 Collection 
    List (ArrayList、LinkedList、Vector)
    Set (HashSet、LinkedHashSet、TreeSet)
public boolean add(E e): 把给定的对象添加到当前集合中 。
•public void clear() :清空集合中所有的元素。
•public boolean remove(E e): 把给定的对象在当前集合中删除。
•public boolean contains(E e): 判断当前集合中是否包含给定的对象。
•public boolean isEmpty(): 判断当前集合是否为空。
•public int size(): 返回集合中元素的个数。
•public Object[] toArray(): 把集合中的元素,存储到数组中。
//创建集合使用多态
Collection<String> coll = new ArrayList<>();

//添加元素add
boolean b = coll.add("李四");
coll.add("张三");
coll.add("张三");
coll.add("王五");
System.out.println(b);//true
System.out.println(coll);//[李四, 张三, 张三, 王五]

//删除元素remove(E e)
coll.remove("张三");
System.out.println(coll);//[李四, 张三, 王五]

//判断当前集合中是否包含给定的对象 contains(E e)
boolean c = coll.contains("张三");
System.out.println(c);//true

//判断当前集合是否为空 isEmpty
System.out.println(coll.isEmpty());//false

//返回集合中元素的个数size
System.out.println(coll.size());//3

// 把集合中的元素,存储到数组中。toArray():
Object[] array = coll.toArray();
for (int i = 0; i < array.length; i++) {
    System.out.print(array[i]+" ");//李四 张三 王五
}

//清空集合中所有的元素。clear() :
coll.clear();
System.out.println(coll);//[]

2.集合遍历的迭代器

Iterator接口的常用方法如下:
public E next():返回迭代的下一个元素。
public boolean hasNext():如果仍有元素可以迭代,则返回 true
Collection c = new ArrayList();
	c.add("a");
	c.add("b");
	c.add("c");
	c.add("d");
Iterator it = c.iterator();						//获取迭代器的引用
while(it.hasNext()) {							//集合中的迭代方法(遍历)
	System.out.println(it.next());
}
/*Iterator it = list.iterator();
while(it.hasNext()) {
	String str = (String)it.next();
	if(str.equals("world")) {
		list.add("javaee");			//这里会抛出ConcurrentModificationException并发修改异常
	}
}*/

3.List

增加:public void add(int index, E element) 
查询:public E get(int index)
删除:public E remove(int index)
修改:public E set(int index, E element)

java.util.ArrayList集合数据存储的结构是数组结构。元素增删慢查找快
java.util.LinkedList集合数据存储的结构是链表结构。方便元素添加删除的集合。

for循环遍历只支持list集合,set集合不可以,因为set集合无索引

4.linkedList集合

LinkedList集合的特点:
        1.底层是一个链表结构:查询慢,增删快
        2.里面包含了大量操作首尾元素的方法
        3.使用LinkedList集合特有的方法,不能使用多态

-    public void addFirst(E e):将指定元素插入此列表的开头。
-    public void addLast(E e):将指定元素添加到此列表的结尾。
-    public void push(E e):将元素推入此列表所表示的堆栈。

-    public E getFirst():返回此列表的第一个元素。
-    public E getLast():返回此列表的最后一个元素。

-    public E removeFirst():移除并返回此列表的第一个元素。
-    public E removeLast():移除并返回此列表的最后一个元素。
-    public E pop():从此列表所表示的堆栈处弹出一个元素。

-    public boolean isEmpty():如果列表不包含元素,则返回true
public static void main(String[] args) {
        show01();
        show02();
        show03();
    }
    private static void show03() {
        LinkedList<String> linked = new LinkedList<>();
        //添加add
        linked.add("abc");
        linked.add("abc");
        linked.add("www");
        System.out.println(linked);//[abc, abc, www]
        //移除第一个元素 removeFirst pop
        String s = linked.removeFirst();
        System.out.println("移除第一个元素"+s);//移除第一个元素abc
        //移除最后一个元素
        String s2 = linked.removeLast();
        System.out.println("移除第一个元素"+s2);//移除第一个元素www
        System.out.println(linked);//[abc]
        
    }
    private static void show02() {
        LinkedList<String> linked = new LinkedList<>();
        //添加add
        linked.add("abc");
        linked.add("abc");
        linked.add("www");
        System.out.println(linked);//[abc, abc, www]
        //linked.clear();//清空 报错 NoSuchElementException
        if (!linked.isEmpty()) {//判断是否为空
            //获取第一个元素
            String first = linked.getFirst();
            System.out.println(first);//abc
            //获取最后一个元素
            String last = linked.getLast();
            System.out.println(last);//www
        }
    }
    private static void show01() {
        LinkedList<String> linked = new LinkedList<>();
        //添加add
        linked.add("abc");
        linked.add("abc");
        linked.add("abc");
        System.out.println(linked);//[abc, abc, abc]
        //头添加元素addFirst(E e) push()
        linked.addFirst("www");
        System.out.println(linked);//[www, abc, abc, abc]
        linked.push("aaa");
        System.out.println(linked);//[aaa, www, abc, abc, abc]
        //尾部添加addLast()
        linked.addLast("com");
        System.out.println(linked);//[aaa, www, abc, abc, abc, com]
    }

5.ListIterator

如果想在遍历的过程中添加元素,可以用ListIterator中的add方法

  • boolean hasNext()是否有下一个
  • boolean hasPrevious()是否有前一个
  • Object next()返回下一个元素
  • Object previous();返回上一个元素
ListIterator lit = list.listIterator();
	while(lit.hasNext()) {
		String str = (String)lit.next();
		if(str.equals("world")) {
			lit.add("javaee");	
			//list.add("javaee");
		}
	}

6.Vector

Vector v = new Vector();                //创建集合对象,List的子类
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d");
//Vector迭代
Enumeration en = v.elements();            //获取枚举
while (en.hasMoreElements()) {            //判断集合中是否有元素
    System.out.println(en.nextElement());//获取集合中的元素
}

7.List的三个子类的特点

ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。

Vector和ArrayList的区别
	Vector是线程安全的,效率低
	ArrayList是线程不安全的,效率高
ArrayList和LinkedList的区别
	ArrayList底层是数组结果,查询和修改快
	LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢

B:List有三个儿子,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList

8.ArrayList去重复

public static ArrayList getSingle(ArrayList list) {
	ArrayList newList = new ArrayList();			//创建一个新集合
	Iterator it = list.iterator();					//获取迭代器
	while(it.hasNext()) {							//判断老集合中是否有元素
		String temp = (String)it.next();			//将每一个元素临时记录住
		if(!newList.contains(temp)) {				//如果新集合中不包含该元素
			newList.add(temp);						//将该元素添加到新集合中
		}
	}
	return newList;									//将新集合返回
}

9.泛型

1.定义和使用含有泛型的类

public class GenericClass<E> {
    private E name;
    public E getName() {
        return name;
    }
    public void setName(E name) {
        this.name = name;
    }
}
GenericClass gc = new GenericClass();
gc.setName("张三");
Object name = gc.getName();
System.out.println(name);//张三

//泛型使用Integer
GenericClass<Integer> gc2 = new GenericClass<>();
gc2.setName(100);
Integer name2 = gc2.getName();
System.out.println(name2);//100

//泛型使用String
GenericClass<String> gc3 = new GenericClass<>();
gc3.setName("李四");
String  name3 = gc3.getName();
System.out.println(name3);//李四

2.含有泛型的方法

public class GenericMethod {
    //定义一个含有泛型的方法
    public <M> void method(M m){
        System.out.println(m);
    }
    //定义一个含有泛型的静态方法
    public static <S> void method2(S s){
        System.out.println(s);
    }
}
GenericMethod gm = new GenericMethod();
gm.method(123);//123
gm.method("abc");//abc
gm.method(true);//true
gm.method('a');//a

gm.method2("静态方法");//静态方法
GenericMethod.method2("abc");//abc
GenericMethod.method2(123);//123

3.含有泛型的接口

public interface GenericInterface<I> {
    public abstract void method(I i);
}
//类不是泛型
public class InterfaceClass implements GenericInterface<String> {
    @Override
    public void method(String s) {
        System.out.println(s);
    }
}
//类是泛型
public class InterfaceClass2<I> implements GenericInterface<I> {
    @Override
    public void method(I i) {
        System.out.println(i);
    }
}
InterfaceClass ic = new InterfaceClass();
ic.method("字符串");//字符串

InterfaceClass2<Integer> ic2 = new InterfaceClass2<>();
ic2.method(10);//10

InterfaceClass2<String> ic3 = new InterfaceClass2<>();
ic3.method("abc");//abc

4.泛型通配符

    ArrayList<String> list = new ArrayList<>();
    list.add("efg");
    list.add("abc");
    ArrayList<Integer> list2 = new ArrayList<>();
    list2.add(123);
    list2.add(456);
    printArray(list);
    printArray(list2);
}

public static void printArray(ArrayList<?> list) {
    Iterator<?> it = list.iterator();
    while (it.hasNext()) {
        Object obj = it.next();
        System.out.println(obj);//efg abc 123 456
    }
}
泛型的上限:

格式: 类型名称 <? extends 类 > 对象名称

意义: 只能接收该类型及其子类

泛型的下限:

格式: 类型名称 <? super 类 > 对象名称

意义: 只能接收该类型及其父类型

Collection<Integer> list1 = new ArrayList<Integer>();
        Collection<String> list2 = new ArrayList<String>();
        Collection<Number> list3 = new ArrayList<Number>();
        Collection<Object> list4 = new ArrayList<Object>();

        getElement1(list1);
        //getElement1(list2);//报错
        getElement1(list3);
        //getElement1(list4);//报错

        //getElement2(list1);//报错
        //getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);

    }
    /*
    类与类之间的继承关系
    Integer extends Number extends Object
    String extends Object
     */
    // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
    public static void getElement1(Collection<? extends Number> coll){}
    // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
    public static void getElement2(Collection<? super Number> coll){}
    }

10.HashSet

存储自定义对象保证元素唯一性(去重复)

1.HashSet原理

  • 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
  • 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
    • 如果没有哈希值相同的对象就直接存入集合
    • 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存

2.将自定义类的对象存入HashSet去重复

  • 类中必须重写hashCode()和equals()方法
  • hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
  • equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储

11.LinkedHashSet

可以保证怎么存就怎么取 产生10个1-20的随机不重复

HashSet<Integer> hs = new HashSet<>();		//创建集合对象
	Random r = new Random();					//创建随机数对象

while(hs.size() < 10) {
	int num = r.nextInt(20) + 1;			//生成1到20的随机数
	hs.add(num);
}

for (Integer integer : hs) {				//遍历集合
	System.out.println(integer);			//打印每一个元素
}
//去重复
public static void getSingle(List<String> list) {
	LinkedHashSet<String> lhs = new LinkedHashSet<>();
	lhs.addAll(list);									//将list集合中的所有元素添加到lhs
	list.clear();										//清空原集合
	list.addAll(lhs);									//将去除重复的元素添回到list中
}

12.TreeSet

  • 1.特点
    • TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
  • 2.使用方式
    • a.自然顺序(Comparable)
      • TreeSet类的add()方法中会把存入的对象提升为Comparable类型
      • 调用对象的compareTo()方法和集合中的对象比较
      • 根据compareTo()方法返回的结果进行存储
    • b.比较器顺序(Comparator)
      • 创建TreeSet的时候可以制定 一个Comparator
      • 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
      • add()方法内部会自动调用Comparator接口中compare()方法排序
    • c.两种方式的区别
      • TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
      • TreeSet如果传入Comparator, 就优先按照Comparator
//对集合中的元素排序,并保留重复
public static void sort(List<String> list) {
    TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {     //定义比较器(new Comparator(){}是Comparator的子类对象)
        @Override
        public int compare(String s1, String s2) {                //重写compare方法
            int num = s1.compareTo(s2);                            //比较内容
            return num == 0 ? 1 : num;                         //如果内容一样返回一个不为0的数字即可
        }
    });
    ts.addAll(list);                                       //将list集合中的所有元素添加到ts中
    list.clear();                                         //清空list
    list.addAll(ts);
}
//从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast程序打印:acehillostt
public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);			//创建键盘录入对象
		System.out.println("请输入一行字符串:");
		String line = sc.nextLine();					//将键盘录入的字符串存储在line中
		char[] arr = line.toCharArray();				//将字符串转换成字符数组
		TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
		@Override
		public int compare(Character c1, Character c2) {
			//int num = c1.compareTo(c2);
			int num = c1 - c2;					//自动拆箱
			return num == 0 ? 1 : num;
		}
	});
	for(char c : arr) {
		ts.add(c);
	}
	for(Character ch : ts) {
		System.out.print(ch);
	}
}

13.Collections

- java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:

- public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
- public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
- public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
- public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
Comparable:强行对实现它的每个类的对象进行整体排序。
Comparator:强行对某个对象进行整体排序

public static void sort(List list,Comparator<? super T> ):将集合中元素按照指定规则排序。

ArrayList<Person> list = new ArrayList<>();

list.add(new Person("a张三",20));
list.add(new Person("c李四",20));
list.add(new Person("b王五",20));

Collections.sort(list, new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
        // 年龄降序
        int result = o2.getAge()-o1.getAge();//年龄降序

        if(result==0) {//第一个规则判断完了 下一个规则 姓名的首字母 升序
            result = o1.getName().charAt(0) - o2.getName().charAt(0);
        }
        return result;
    }
});
        System.out.println(list);
//[Person{name='a张三', age=20}, Person{name='b王五', age=20}, Person{name='c李四', age=20}]

模拟斗地主的洗牌和发牌

String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
	String[] color = {"方片","梅花","红桃","黑桃"};
	ArrayList<String> poker = new ArrayList<>();
for(String s1 : color) {
	for(String s2 : num) {
		poker.add(s1.concat(s2));
	}
}
poker.add("小王");
poker.add("大王");
//洗牌
Collections.shuffle(poker);
//发牌
ArrayList<String> gaojin = new ArrayList<>();
ArrayList<String> longwu = new ArrayList<>();
ArrayList<String> me = new ArrayList<>();
ArrayList<String> dipai = new ArrayList<>();
for(int i = 0; i < poker.size(); i++) {
	if(i >= poker.size() - 3) {
		dipai.add(poker.get(i));
	}else if(i % 3 == 0) {
		gaojin.add(poker.get(i));
	}else if(i % 3 == 1) {
		longwu.add(poker.get(i));
	}else {
		me.add(poker.get(i));
	}
}
//看牌
System.out.println(gaojin);
System.out.println(longwu);
System.out.println(me);
System.out.println(dipai);

13.Map

在这里插入图片描述

A:Map接口概述
  • 查看API可以知道:
    • 将键映射到值的对象
    • 一个映射不能包含重复的键
    • 每个键最多只能映射到一个值
B:Map接口和Collection接口的不同
  • Map是双列的,Collection是单列的
  • Map的键唯一,Collection的子体系Set是唯一的
  • Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

14.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():???
  • V get(Object key):根据键获取值
  • Set keySet():获取集合中所有键的集合
  • Collection values():获取集合中所有值的集合

5:长度功能

  • int size():返回集合中的键值对的个数

15.Map的两种循环方式

//keySet
Set<String> keySet = hm.keySet();			//获取集合中所有的键
Iterator<String> it = keySet.iterator();	//获取迭代器
while(it.hasNext()) {						//判断单列集合中是否有元素
	String key = it.next();					//获取集合中的每一个元素,其实就是双列集合中的键
	Integer value = hm.get(key);			//根据键获取值
	System.out.println(key + "=" + value);	//打印键值对
}
//增强for
for(String key : hm.keySet()) {				//增强for循环迭代双列集合第一种方式
	System.out.println(key + "=" + hm.get(key));
}
//entrySet
Set<Map.Entry<String, Integer>> entrySet = hm.entrySet();	//获取所有的键值对象的集合
	Iterator<Entry<String, Integer>> it = entrySet.iterator();//获取迭代器
	while(it.hasNext()) {
		Entry<String, Integer> en = it.next();				//获取键值对对象
		String key = en.getKey();								//根据键值对对象获取键
		Integer value = en.getValue();							//根据键值对对象获取值
		System.out.println(key + "=" + value);
	}
//增强for
    for(Entry<String,Integer> en : hm.entrySet()) {
	System.out.println(en.getKey() + "=" + en.getValue());
}

16.HashMap

当给 HashMap 中存放自定义对象时,如果自定义对象作为key存在
这时要保证对象唯一必须复写对象的 hashCodeequals 方法

统计每个字符出现的个数

String str = "aaaabbbcccccccccc";
	char[] arr = str.toCharArray();						//将字符串转换成字符数组
	HashMap<Character, Integer> hm = new HashMap<>();	//创建双列集合存储键和值
for(char c : arr) {									//遍历字符数组
	if(!hm.containsKey(c)) {						//如果不包含这个键
		hm.put(c, 1);								//就将键和值为1添加
	}else {											//如果包含这个键
		hm.put(c, hm.get(c) + 1);					//就将键和值再加1添加进来
	}
//hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);
Integer i = !hm.containsKey(c) ? hm.put(c, 1) : hm.put(c, hm.get(c) + 1);
		}
for (Character key : hm.keySet()) {					//遍历双列集合
	System.out.println(key + "=" + hm.get(key));
}

17.LinkedHashMap

有序集合、顺序打印:

 LinkedHashMap<String, String> map = new LinkedHashMap<>();
    map.put("a","a");
    map.put("b","b");
    map.put("c","c");
    map.put("a","d");
    Set<Map.Entry<String, String>> set = map.entrySet();
    for (Map.Entry<String, String> entry : set) {
        String key = entry.getKey();
        String value = entry.getValue();
        System.out.println(key +"= " + value);//a= d b= b c= c
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值