此博客为看B老师Java视频的部分记录
- 泛型
- 给编译器使用的技术。使用容器时,就明确容器中元素的类型,这种机制称为泛型使用格式:<数据类型>,括号里的东西为参数
List<String> list = new ArrayList<String>();
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class GenericTest {
public static void main(String[] args) {
// 创建一个唯一性元素集合并按照朝阳都排序,需要比较器,匿名内部类完成
Set<String> set = new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int temp = o1.length() - o2.length();
return temp == 0 ? o1.compareTo(o2) : temp;
}
});
// 添加元素
set.add("abcde");
set.add("java");
set.add("hello");
for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
String string = it.next();
System.out.println(string);
}
}
}
- 泛型类:泛型定义在类上
class Tool<Q>{
private Q object;
public Q getObject(){
return object;
}
public void setObject (Q object){
this.object = object;
}
}
- 泛型方法
class Util<W>{
// 当方法要操作的类型不确定和类上的泛型不一定一样。这时可以将泛型定义在方法上
public <Q> void show(Q q){ // 泛型方法
System.out.println("show:"+q);
}
public static<E> void print(E e){// 如果方法是静态,还需要使用泛型,那么泛型必须定义在方法上
System.out.println("print:"+e);
}
}
- 泛型接口
interface Inter<E>{
void show(E e);
}
// 若子类能明确类型则直接写
//class InterImpl implements Inter<String>{
// public void show(String e){}
//}
class InterImpl<T> implements Inter<T>{
@Override
public void show(T e){}
}
/*
public static void main(String[] args){
new InterImpl<String>().show("hehe");
}
*/
- 泛型通配符
当使用泛型类或者接口时,传递的具体的类型不确定,可以通过通配符(?)表示
private static void printList(Collection<?> list2){
for(Iterator<?> it = list2.iterator(); it.hasNext();){
System.out.println(it.next().toString());
}
}
-
通配符限定
-
使用泛型,要保证左右类型一致,如
ArrayList<String> a1 = new ArrayList<String>();
-
工具类
-
Collections:集合框架中的用于操作集合对象工具类
- 都是静态的工具方法
- 获取Collection最值
- 对List集合排序,也可以二分查找
- 对排序逆序
- 可以将非同步的集合转成同步的集合
Xxx synchronizedXxx(Xxx) 如: List synchronizedList(List)
-
Arrays : 用于操作数组的工具类
- 类中定义的都是静态工具方法
- 对数组排序
- 二分查找
- 数组复制
- 对两个数组进行元素的比较,判断两个数组是否相同
- 将数组转为字符串
-
-
数组转成集合:
- 为了使用集合的方法操作数组中的元素,但不要使用增删(add remove)等改变长度的方法,否则发生UnsupportedOperationException。数组长度是固定的,转成List集合长度也是固定的
- 将数组转成集合,如果数组中存储的是基本数据类型,那么转成集合,数组对象会作为集合中的元素存在;如果数组中元素是引用数据类型时,转成集合,数组元素会作为集合元素存在
-
集合转成数组
- 为了限制对元素的增删操作
- 如果传递的数组的长度小于集合的长度,会创建一个同类型的数组长度为集合的长度;如果传递的数组的长度大于集合的长度,就会使用这个数组,没有存储元素的位置为null;长度最好直接定义为和集合长度一致
传递数组的长度大于集合长度:
- Map集合(类比python中的字典)
-
特点:
- 内部存储的都是键值对(key-value)
- 必须要保证键的唯一性
-
Map
- Hashtable:数据结构:哈希表。是同步的,不允许null作为键和值。被hashmap替代
- Properties: 属性集,键和值都是字符串,而且可以结合流进行键值的操作
- HashMap:数据结构:哈希表。不是同步的,允许null作为键和值
- LinkedHashMap:基于链表+哈希表,可以保证map集合有序(存入和取出的顺序一致)
- TreeMap: 数据结构:二叉树。不是同步的,可以对map集合中的键进行排序
- Hashtable:数据结构:哈希表。是同步的,不允许null作为键和值。被hashmap替代
-
- 什么时候使用map集合?
分析问题时,出现对应关系,首先想到map集合;如果对应关系中出现了有序的数字,想到数组。如果对应关系个数不确定,还是以map为主
import java.util.HashMap;
import java.util.Map;
public class MapDemo01 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
// 添加元素
System.out.println(map.put("星期一", "Monday")); // 此时打印为结果null,因为没有星期一没有对应的旧值
// System.out.println(map.put("星期一", "Mond")); // 打印结果为Monday
// 如果键相同,值覆盖。put方法会返回旧值,没有旧值则为null
map.put("星期日", "Sunday");
// 通过给定值获取值
String value = map.get("星期二"); // 如果键不存在,返回null,可通过此方法来判断键是否存在
System.out.println("value=" + value);
// 删除元素,根据键删除
String s = map.remove("星期一"); // 获取给定键对应的值,并将该键值对从map集合删除
System.out.println("s=" + s);
System.out.println(map);
}
}
运行结果
- keySet、entrySet、values
import java.util.*;
public class MapDemo2 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("星期一", "Monday");
map.put("星期日", "Sunday");
System.out.println("-------KeySet方法获取--------");
// Set<k> KeySet(); 用于获取map集合中键的set集合
Set<String> KeySet = map.keySet();
// 普通for循环获取
for (Iterator<String> it = KeySet.iterator(); it.hasNext(); ) {
String key = it.next();
String value = map.get(key); // 通过键获取对应的值
System.out.println(key + "::" + value);
}
// foreach循环进行遍历
for (String key : KeySet) {
System.out.println(key + ":::" + map.get(key));
}
System.out.println("-------entrySet方法获取--------");
// Set entrySet():将map集合中映射关系存储到了Set集合中
// 映射关系:键和值的对应关系,是Map.Entry类型
Set<Map.Entry<String, String>> entrySet = map.entrySet();
Iterator<Map.Entry<String, String>> it = entrySet.iterator();
// 遍历Set中的映射关系对象
while (it.hasNext()) {
Map.Entry<String, String> me = it.next(); // 取到了映射关系对象
// 获取键
String key = me.getKey();
// 获取值
String value = me.getValue();
System.out.println(key + "---" + value);
}
// map集合没有迭代器,取出元素的方式 : 将map集合转成单列结合,再使用单列集合的迭代器
for (Map.Entry<String, String> me : map.entrySet()) {
String key = me.getKey();
// 获取值
String value = me.getValue();
System.out.println(key + "---------" + value);
}
System.out.println("-------获取所有值的方法values()--------");
// 获取所有的值,因为值不需要保证值的唯一性,所以返回类型 collection
Collection<String> values = map.values();
for (String value : values) {
System.out.println("value : " + value);
}
}
}
运行结果
- 小练习
Student.java
package CompareDemo;
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String zs, int i) {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
- HashMap
import CompareDemo.Student;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapDemo01 {
public static void main(String[] args) {
// 练习:学生对象(姓名、年龄)都有自己的归属地,既然有对应关系,so将学生对象和归属地存储到map集合中
// 创建hashmap集合对象
Map<Student, String> map = new HashMap<Student, String>();
// 添加元素
map.put(new Student("zs", 28), "上海");
map.put(new Student("ls", 22), "北京");
map.put(new Student("zss", 25), "成都");
map.put(new Student("lss", 25), "南京");
// 取出元素 keySet、entrySet
// Set<Student> keySet = map.keySet();
//for (Student key : keySet) {}
for (Student key : map.keySet()) {
String value = map.get(key);
System.out.println(key.toString() + "..." + value);
}
}
}
运行结果
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
public static void main(String[] args) {
/* 练习:”e+j-ja=dja-lq=wer“,获取字符串中每一个字母出现的次数
* 要求返回结果格式为 a(1)b(2)...;
* 思路分析;
* 1. 获取到字符串中的每一个字母
* 2. 用字母去查表,如果查到了该字母对应的次数,就将这个次数+1后重新存入表中,如果没查到则将数字 1 存入表中
* 3. 每一个字母都查完表后,表中记录所有字母出现的次数
*
* 字母和次数之间存在对应关系,而且字母唯一,所以可用map集合做表进行查询,通过结果发现字母又顺序,所以可通过map集合中的treemap作为表
*/
String str = "ejjadjalqwer";
str = getCharCount(str);
System.out.println(str);
}
// 获取字符串中字母出现次数
private static String getCharCount(String str) {
// 1.将字符串转为字符数组
char[] chs = str.toCharArray();
// 2.定义表
TreeMap<Character, Integer> map = new TreeMap<Character, Integer>();
// 3.遍历字符串
for (int i = 0; i < chs.length; i++) {
// 判断必须是字母
if (!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z')) {
continue;
}
// 4. 将遍历到的字母作为键去查map这个表,获取对应的次数
Integer value = map.get(chs[i]);
// 5. 有可能要查询的字母在表中不存在对应的次数,需要判断
// 如果返回的是null,说明字母没有对应的次数,就将这个字母和1存储到表中
if (value == null) {
// 将字母和 1 存储
map.put(chs[i], 1);
} else {
//否则,说明有对应的次数对次数自增。将字母和新的次数存储到表中
value++;
map.put(chs[i], value);
}
}
return maptoString(map);
}
// 将map集合中的键值转为 a(1)b(2)...格式
// map中有很多数据,无论多少个,是什么类型,最终都变成字符串,StringBuffer符合此需求。
// 如果是单线程,优先使用StringBuilder
private static String maptoString(Map<Character, Integer> map) {
// 1.明确容器
StringBuilder sb = new StringBuilder();
// 2. 遍历map集合
for (Character key : map.keySet()) {
Integer value = map.get(key);
sb.append(key + "(" + value + ")");
}
return sb.toString();
}
}
运行结果
-
可变参数
-
静态导入
- System、System分隔符、Math
Math数学运算,方法都是静态的
Math.PI
上一篇:Java基础记录(五)
下一篇:Java基础记录(七)