初学List和Set集合
一、List和Set集合都属于Collection。
1、List系列集合:添加的元素是有序、可重复、有索引。
ArrayList、LinekdList:有序、可重复、有索引。
2、Set系列集合:添加的元素是无序、不重复、无索引。
HashSet:无序、不重复、无索引;
LinkedHashSet:有序、不重复、无索引。
TreeSet:按照大小默认升序排序、不重复、无索引。
3、集合和泛型不支持基本类型,只支持引用数据类型。
二、集合的遍历方式
1、迭代器
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("java");
System.out.println(list);
// 1、得到当前集合的迭代器对象
Iterator<String> it = list.iterator();
// 2、定义while循环
while (it.hasNext()){
String ele = it.next();
System.out.println(ele);
}
}
2、foreach/增强for循环
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("java");
System.out.println(list);
// 增强for
for (String ele : list){
System.out.println(ele);
}
System.out.println("------------------");
double[] scores = {90.5,100,79.5};
for (double score : scores) {
System.out.println(score);
}
}
3、lambda表达式
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("张三");
list.add("赵敏");
list.add("黑马");
list.add("java");
System.out.println(list);
// list.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
// list.forEach( s -> {
// System.out.println(s);
// });
// list.forEach( s -> System.out.println(s) );
list.forEach(System.out::println);
}
接下来开始进入正题:
三、 List系列集合
1、List系列集合特点
①ArrayList、LinekdList:有序,可重复,有索引。
②有序:存储和取出的元素顺序一致
③有索引:可以通过索引操作元素
④可重复:存储的元素可以重复
2、List集合的遍历方式有4种
①迭代器
②增强for循环
③Lambda表达式
④for循环(因为List集合存在索引)
代码如下:
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("java1");
list.add("java2");
list.add("java3");
/**
* for循环
*/
for (int i = 0; i < list.size(); i++) {
String ele = list.get(i);
System.out.println(ele);
}
/**
* 迭代器
*/
System.out.println("-------------------------");
Iterator<String> it = list.iterator();
while (it.hasNext()){
String ele1 = it.next();
System.out.println(ele1);
}
/**
* 增强for
*/
System.out.println("------------------------");
for (String ele2: list) {
System.out.println(ele2);
}
/**
* JDK8之后 Lambda表达式
*/
System.out.println("------------------------");
list.forEach(s -> {
System.out.println(s);
});
}
3、ArrayList集合底层原理
①ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。
②第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组。
4、LinkedList集合底层原理
底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的特有功能
public static void main(String[] args) {
// LinkedList可以完成队列结构,和栈结构
// 双链表
// 栈
LinkedList<String> stack = new LinkedList<>();
// 压栈,入栈
// stack.addFirst("第1颗子弹");
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack);
// 出栈 弹栈
// System.out.println(stack.removeFirst());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack);
// 队列
LinkedList<String> queue = new LinkedList<>();
// 入队
queue.addLast("1号");
queue.addLast("2号");
queue.addLast("3号");
queue.addLast("4号");
System.out.println(queue);
// 出队
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue.removeFirst());
System.out.println(queue);
}
运行结果如下:
四、Set系列集合
1、Set系列集合特点
①无序:存取顺序不一致
②不重复:可以去除重复
③无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。
2、Set集合实现类特点
①HashSet : 无序、不重复、无索引。
②LinkedHashSet:有序、不重复、无索引。
③TreeSet:排序、不重复、无索引。
3、HashSet底层原理
①HashSet集合底层采取哈希表存储的数据。
②哈希表是一种对于增删改查数据性能都较好的结构。
③JDK8之前的,底层使用数组+链表组成
④JDK8开始后,底层采用数组+链表+红黑树组成。
4、哈希表的详细流程
①创建一个默认长度16,默认加载因为0.75的数组,数组名table
②根据元素的哈希值跟数组的长度计算出应存入的位置
③判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素, 则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组。
④ 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍
5、LinkedHashSet集合概述和特点
①有序、不重复、无索引。
②这里的有序指的是保证存储和取出的元素顺序一致
③原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。
6、根据此节集合写的一个斗地主发牌程序
public class Card {
private String size;
private String color;
private int index; // 牌的真正大小
public Card() {
}
public Card(String size, String color, int index) {
this.size = size;
this.color = color;
this.index = index;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
@Override
public String toString() {
return color + size;
}
}
/**
* 斗地主:发出51张牌,留3张底牌
*/
public class GameDemo {
/**
* 1、定义一个静态集合存储54张牌对象
*/
public static List<Card> allCards = new ArrayList<>();
/**
* 2、做牌,定义静态代码块初始化牌数据
*/
static {
// 3、定义点数:个数确定,类型确定,使用数组
String[] sizes = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
// 4、定义花色:个数确定,类型确定,使用数组
String[] colors = {"♠️", "♥️", "♣️", "♦️"};
// 5、组合点数和花色
int index = 0; //记录牌的大小
for (String size : sizes) {
index++;
for (String color : colors) {
// 6、封装成一个牌对象
Card c = new Card(size,color,index);
// 7、存到集合容器中
allCards.add(c);
}
}
// 8、大小王存入到集合对象中去
Card c1 = new Card("","🧞",++index);
Card c2 = new Card("","🧜",++index);
Collections.addAll(allCards,c1,c2);
System.out.println("新牌:"+allCards);
}
public static void main(String[] args) {
// 9、洗牌
Collections.shuffle(allCards);
System.out.println("洗牌后:"+allCards);
// 10、发牌(定义三个玩家,每个玩家的牌也是一个集合容器)
List<Card> zhangsan = new ArrayList<>();
List<Card> lisi = new ArrayList<>();
List<Card> wangwu = new ArrayList<>();
// 11、开始发牌(从牌集合中发出51张牌给三个玩家,剩余3张作为底牌)
for (int i = 0; i < allCards.size() - 3; i++) {
// 先拿到当前牌对象
Card c = allCards.get(i);
if (i%3==0){
zhangsan.add(c);
}else if (i%3==1){
lisi.add(c);
}else if (i%3==2){
wangwu.add(c);
}
}
// 12、拿到最后三张底牌(把最后三张牌截取成一个子集合)
List<Card> lastThreeCards = allCards.subList(allCards.size()-3,allCards.size());
// 13、给玩家的牌排序(从大到小)
sortCards(zhangsan);
sortCards(lisi);
sortCards(wangwu);
// 14、输出玩家的牌:
System.out.println("张三:" + zhangsan);
System.out.println("李四:" + lisi);
System.out.println("王五:" + wangwu);
System.out.println("三张底牌:" + lastThreeCards);
}
/**
* 给牌排序
* @param cards
*/
private static void sortCards(List<Card> cards){
Collections.sort(cards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return o2.getIndex() - o1.getIndex();
}
});
}
}
运行结果如下:
文章写的不是很全面,希望大佬指正。
这次就先分享到这里,下次分享Map集合。