今日内容
Map
可变参数
Stream流
数据结构演示网站
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
哈希值
同一个对象的哈希值一定相同
不同对象的哈希值可能相同
总结:
如果哈希值不同一定不是同一个对象
哈希值相同可能是同一个对象也可能不是同一个对象
HashSet去重的原理:
依赖hashCode和equals方法的
hashCode用于计算哈希值,这个方法一定会执行的
equals方法用于进一步判断的(哈希值相同的时候,还需要equals方法进一步判断是否是同一个对象),
它不一定会执行。
通过hashCode方法计算哈希值,然后根据哈希值计算在数组中的存储位置,如果该位置上没有元素,则直接存入。
如果该位置上有元素,则需要通过equals方法进一步判断对象中的成员变量是否完全一样,如果一样,则不存入,
如果不一样,则存入。
Map体系结构
Map接口
|-HashMap
|-TreeMap
什么是Map
<K,V>
Map的特点
键不能重复,值可以重复
如果键重复,则会值覆盖
一个键只能找到一个唯一的值,键值对是一一对应的
HashMap的键的特点和HashSet的特点一样
TreeMap的键的特点和TreeSet的特点一样
Map是存储无序的
Map是无索引的,不能通过索引来操作元素
Map的基本使用
1、创建对象
2、添加元素
3、遍历(调用toString方法打印)
Map集合的遍历
Map<String,String> map = new HashMap<>();
map.put("1号丈夫","1号妻子");
map.put("2号丈夫","2号妻子");
map.put("3号丈夫","3号妻子");
map.put("4号丈夫","4号妻子");
map.put("5号丈夫","5号妻子");
//获取到所有的键
Set<String> keys = map.keySet();
//遍历Set集合得到每一个键
for (String key : keys) {
//通过每一个键key,来获取到对应的值
String value = map.get(key);
System.out.println(key + "---" + value);
}
Map
常用方法
删除
void clear()
V remove(Object key)
添加/修改
V put(K key, V value)
判断
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
获取(遍历)
int size()
Set<K> keySet()
V get(Object key)
Set<Map.Entry<K,V>> entrySet()
第二种遍历方式(通过键值对对象找键和值)
步骤:
1、获取所有的键值对对象(Entry),返回的是Set集合
2、遍历Set集合,获取到每一个键值对对象
3、通过键值对对象中的getKey()和getValue()方法分别获取键和值
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
//得到每一个键值对对象
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "---" + value);
}
HashMap
HashMap的底层原理和HashSet是一致的,
因为HashSet底层使用的就是HashMap,使用的是哈希表结构
数据结构只是对键有效,而HashSet使用的就是HashMap中的键
Set集合的数据结构和Map集合的键的数据结构是一致的。
TreeMap
和HashMap的使用基本上是一样的,因为它和HashMap都是Map的实现类,Map中的功能它都能用。
不同的是TreeMap底层使用的红黑树,底层的数据结构不同导致存储的特点不同。TreeMap可以对
键值对中的键进行排序,排序可以使用自然排序和比较器排序,如果说操作上有什么不同,就是
如果使用自然排序,则排序的元素所在的类需要实现Comparable接口,如果使用比较器排序则需要传递
比较器对象。
可变参数
JDK1.5的新特性,参数个数可以发生变化,可以是0个、1个和多个。
可变参数只能使用在方法的形参位置,即方法的小括号中
格式: 修饰符 返回值类型 方法名(数据类型... 变量名) {}
注意事项:
1、本质是一个数组
2、可以传递0个、1个和多个值
3、如果一个方法的参数有多个,并且包含可变参数,那么可变参数必须位于最后一个参数位置.
一个方法的可变参数只能有一个
Stream流
Stream流可以简化集合和数组的一些操作。
Stream流的操作
1、将数据源(集合和数组)转为Stream流
* 获取Stream流
2、调用Stream流中的方法操作数据
* 中间方法:返回的是Stream流对象,可以继续对流进行操作
* 终结方法:返回的不是Stream流对象,不可以继续对流进行操作
3、Stream流转为集合和数组(收集流)
将数据源(集合和数组)转为Stream流(获取Stream流)
集合
单列集合 : 集合对象.stream();
双列集合 : 不能直接获取,需要间接获取
集合对象.keySet().stream();
集合对象.entrySet().stream();
数组
数组 :
Arrays.stream(数组名);
同种数据类型的多个数据:
Stream.of(数据1,数据2,数据3......);
总结:集合转Stream选 集合对象.stream()方法,
数组转Stream选 Stream.of()方法
一个流只能使用一次
调用Stream流中的方法操作数据(都是Stream中的方法)
中间方法
Stream<T> filter(Predicate<? super T> predicate); 过滤流中的数据,满足条件的数据留下
Stream<T> limit(long n); 截取前n个,其余的舍弃
Stream<T> skip(long n); 跳过前n个,其余的都留下
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):拼接流
Stream<T> distinct(); 去除流中重复的数据
终结方法
void forEach(Consumer<? super T> action);
long count();
Stream流转为集合和数组(收集流)
收集到集合
* <R, A> R collect(Collector<? super T, A, R> collector);
* Collectors.toList()
* Collectors.toSet()
* Collectors.toCollection()
ArrayList<Integer> list = list1.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toCollection(new Supplier<ArrayList<Integer>>() {
@Override
public ArrayList<Integer> get() {
return new ArrayList<>();
}
}));
* Collectors.toMap()
收集到数组
Object[] toArray();
Object[] objects = list1.stream().filter(number -> number % 2 == 0).toArray();
<A> A[] toArray(IntFunction<A[]> generator);
Integer[] integers = list1.stream().filter(number -> number % 2 == 0)
.toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
import java.util.Enumeration;
import java.util.Vector;
/*
面试题:
Vector和ArrayList的区别?
ArrayList是用于替代Vector的,Vector出现非常早(JDK 1.0出现),
比集合体系(框架)出现的还早,JDK1.2才出现集合框架
1、Vector是线程安全的(不同的),效率低
ArrayList是线程不安全的(不同步的),效率高
2、ArrayList方法的名称做了很大的简化
Enumeration和Iterator的区别?
Iterator是用于替代Enumeration的,Enumeration是老的迭代器
1、Iterator的功能比Enumeration稍微强大一点,
Iterator可以在遍历的时候调用remove方法,而Enumeration没有
2、Iterator中的方法名称做了简化
*/
public class VectorDemo {
public static void main(String[] args) {
// void addElement(E obj) -- add
// E elementAt(int index) -- get(int index)
// boolean removeElement(Object obj) -- remove(Object obj)
// void removeElementAt(int index) - remove(int index)
// void removeAllElements() -- clear
// void setElementAt(E obj, int index) -- set(int index,Object obj)
// Enumeration<E> elements() -- iterator
Vector<String> v = new Vector<>();
v.addElement("hello");
v.addElement("world");
v.addElement("java");
v.addElement("php");
Enumeration<String> en = v.elements();// 相当于是老的迭代器 Iterator<String> it = list.iterator();
while(en.hasMoreElements()){// it.hasNext()
String s = en.nextElement();// it.next()
System.out.println(s);
}
System.out.println("--------------");
for (int i = 0; i < v.size(); i++) {
System.out.println(v.elementAt(i));
}
}
}