Java集合(二)

Set
  方法介绍
  特点
  List利用Set去重
  总结
Queue
  介绍
  常用操作
  总结
  PriorityQueue
    介绍
    总结
  Deque
    介绍
    Deque和Queue区别
    基本使用
    总结
Stack
  介绍
  Stack作用
总结

Set

方法介绍
  • boolean add(E e) 添加元素
  • boolean remove(Object o) 移除元素
  • boolean contains(Object o) 是否包含元素
  • int size() 元素个数
Set<String> set = new HashSet<>();
set.add("abc");	// true
set.add("xyz");	// true
set.size(); // 2
set.add("xyz");	// false
set.size();	// 2
set.contains("abc"); // true
set.remove("abc"); // true
set.size();	// 1
set.contains("abc"); // false
set.remove("test");	// false
set.size();	// 1
特点

Set用于存储不重复的元素集合:

  • Set实际上相当于不存储Value的Map
  • Set用于去除重复元素
  • 放入Set的元素要正确实现equals()和hashCode()

Set不保证有序:

  • HashSet是无序的
  • TreeSet是有序的
  • 实现了SortedSet接口的是有序Set
    在这里插入图片描述
Set<String> set = new HashSetM<>();
set.add("apple");
set.add("banana");
set.add("orange");
for (String s : set) {
  	System.out.println(s);
}
// 无序的 banana, orange, apple

Set<String> set = new TreeSet<>();
set.add("banana");
set.add("apple");
set.add("orange");
for (String s : set) {
  	System.out.println(s);
}
// 有序的 apple, banana, orange

自定义排序算法:

Set<String> set = new TreeSet<>(new Comparator<String>(){
  	public int compare(String o1, String o2) {
				// 倒序排序
      	return - o1.compareTo(o2);
    }
});
set.add("banana");
set.add("apple");
set.add("orange");
for (String s : set) {
  	System.out.println(s);
}
// 倒序的 orange, banana, apple
List利用Set去重
List<String> list = Arrays.asList("pear", "apple", "banana", "apple");
// 转化为set去重
Set<String> set = new HashSet<>(list);
// 或转化为TreeSet去重并排序
// Set<String> set = new TreeSet<>(list);
// 再转化为List
List<String> list1 = new ArrayList<String>(set);

// 自定义排序算法
Set<String> set2 = new TreeSet<>(new Comparator<String>() {
  	public int compare(String o1, String o2) {
      	// 倒序
      	return - o1.compareTo(o2);
    }
});
// 把list数据添加到set
set2.addAll(list);
// 再转化为List
List<String> list2 = new ArrayList<String>(set2);
总结
  • Set用于存储不重复的元素集合
  • 放入Set的元素与作为Map的Key要求相同:
    • 正确实现equals()和hashCode()
  • 利用Set可以去除重复元素
  • 遍历SortedSet按照元素的排序顺序遍历,也可以自定义排序算法

Queue

介绍

Queue实现了一个先进先出(FIFO)的队列

  • FIFO:First In First Out
  • LinkedList实现了Queue接口
常用操作
  • 获取队列长度:size()
  • 添加元素倒队尾:boolean add(E e) / boolean offer(E e)
Queue<String> q = new LinkedList<>();
if (q.offer("abc")) {
  	// add ok
} else {
  	// add failed
}
  • 获取队列头部元素并删除:E remove() / E poll()
Queue<String> q = new LinkedList<>();
if (q.isEmpty()) {
  	// cannot poll
} else {
  	String first = q.poll();
}
  • 获取队列头部元素但不删除:E element() / E peek()
Queue<String> q = new LinkedList<>();
if (q.isEmpty()) {
  	// cannot peek
} else {
  	String first = q.peek();
}
  • 当添加或获取元素失败时,以上提供的两种方法的区别:
    在这里插入图片描述
总结
  • Queue 实现一个先进先出(FIFO)的队列
  • add / offer 将元素添加到队尾
  • remove / poll 从队首获取元素并删除
  • element / peek 从队首获取元素但不删除
  • 避免把null添加到队列
PriorityQueue
介绍

PriorityQueue的出队顺序与元素的优先级有关,父类AbstractQueue实现了Queue:

  • remove() / poll() / element() / peek() 总是取优先级最高的元素
  • 默认情况下PriorityQueue中的元素要实现Comparable接口,并实现compareTo方法
public class Person implements Comparable<Person> {
		private String name;
  	private int age;
  	public Person(String name, int age) {
      	this.name = name;
      	this.age = age;
    }
    @Override
    public int compareTo(Repository o) {
      	// 按name排序
        return name.compareTo(o.name);
    }  
}

public class Main {
  	public static void main(String[] arge) {
      	PriorityQueue<Person> queue = new PriorityQueue<>();
      	queue.offer(new Person("Lili", 18));
      	queue.offer(new Person("Aiice", 20))
        System.out.println(queue.peek());
      	// Person{name='Alice', age=20}
      	// compareTo方法改为 return - name.compareTo(o.name); 降序排序
      	// 结果为Person{name='Lili', age=18}
    }
}
  • 也可以通过自定义排序算法来排序,这样就不用元素类实现接口了
public class Main {
  	public static void main(String[] arge) {
      	PriorityQueue<Person> queue = new PriorityQueue<>(new Comparator<Person>(){
          	@Override
            public int compare(Person1 o1, Person1 o2) {
              	// 倒序
                return - o1.name.compareTo(o2.name);
            }
        });
      	queue.offer(new Person("Lili", 18));
      	queue.offer(new Person("Aiice", 20))
        System.out.println(queue.peek());
      	// 结果为Person{name='Lili', age=18}
    }
}
总结
  • PriorityQueue实现了一个优先队列
  • 从队首获取元素时,总是获取优先级最高的元素
  • 默认按元素比较的顺序排序(必须实现Comparable接口)
  • 可以通过Comparator自定义排序算法(不用实现Comparable接口)

#####Deque

介绍

Deque实现一个双端队列(Double Ended Queue)继承自Queue:

  • 既可以添加到队尾,也可以添加到队首
  • 既可以从队首获取, 又可以从队尾获取
Deque和Queue区别

在这里插入图片描述
在这里插入图片描述

基本使用
  • 为了和Queue方法相区分,使用Deque时总是使用xxxFist / xxxLast方法
Deque<String> deque = new LinkedList<>();
deque.offerLast("end");
deque.offerFirst("abc");
String last = deque.peekLast();
String first = deque.peekFirst();
  • Deque的实现类:ArrayDeque, LinkedList

因为LinkedList既实现了List接口,又实现了Deque接口,因此使用时习惯用接口类型来接收:

Deque<String> deque = new LinkedList<>();
deque.offerLast("z");

List<String> list = new LinkedList<>();
list.add("abc");

如果使用LinkedList来引用自己,则无法看出其具体是用作List还是Deque

// 不要这样写
LinkedList<String> obj = new LinkedList<>();
obj.offerLast("z");
总结
  • Deque 实现了一个双端队列(Double Ended Queue)
  • 将元素添加到队尾 / 队首:addLast / offerLast / addFirst / offerFirst
  • 从队首 / 队尾获取元素并删除:removeFirst / pollFirst / removeLast / pollLast
  • 从队首 / 队尾获取元素但不删除:getFirst / peekFirst / getLast / peekLast
  • 总是调用xxxFirst / xxxLast 以便与Queue的方法区分开
  • 避免把null添加到队列

Stack

介绍

栈(Stack)是一种后进先出(LIFO)的数据结构

  • LIFO:Last In First Out
  • push(E e):把元素压栈
  • pop(E e):把栈顶的元素“弹出”

用Deque可以实现Stack的功能:

  • push(E e):addFirst(E e)
  • pop():removeFirst()
  • peek():peekFirst()
Stack的作用
  • 方法(函数)的嵌套调用
  • 嵌套调用过多会造成栈溢出StackOverflowError
  • 将整数转换为十六进制表示的String:12500 -> 0x30d4
12500 / 16 = 781...44压栈
781 / 16 = 48...d 	 把d压栈
48 / 16 = 3...00压栈
3 / 16 = 0...33压栈
// 依次从栈顶取出为 30d4
  • 将中缀表达式编译为后缀表达式进行计算
/*
中缀表达式:1 + 2 * (9 - 5)
编译器编译后
后缀表达式:1 2 9 5 - * +
计算过程:
1 2 9 5 依次压栈
遇到-,把5和9弹出,并计算-5+9得到4,把4压栈
遇到*,把4和2弹出,并计算4*2得到8,把8压栈
遇到+,把8和1弹出,并计算8+1得到9,把9压栈
计算结束,弹出9得到最终结果
*/
总结
  • 栈(Stack)是一种后进先出(LIFO)的数据结构
  • 操作栈的元素的方法
    • push(E e):压栈
    • pop():出栈
    • peek():取栈顶元素但不出栈
  • Java使用Deque实现栈的功能,注意只调用push / pop / peek,避免调用Deque其他方法
  • 不要使用遗留类Stack
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌影~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值