一、包装类
基本数据类型对应的引用数据类型
1.各个类型对应的包装类
!!!包装类的特点
2.获取Integer对象的方式 (其他类似)
a.用构造方法获取Integer的对象 JDK5以前
b.用静态方法获取Integer的对象
package com.itheimademo1.MathDemo2;
public class IntegerTry {
public static void main(String[] args) {
//1.
Integer i1 = new Integer(1);
//2.
Integer i2 = Integer.valueOf(123);
}
}
3.自动装箱和自动拆箱 JDK5 以后
自动装箱:把基本数据类型自动的变成对应的包装类
自动拆箱:把包装类自动的变成其对象的基本数据类型
package com.itheimademo1.MathDemo2;
public class IntegerTry {
public static void main(String[] args) {
//在底层还是会自动调用valueof得到一个Integer对象 只不过这个动作不需要自己操作
//自动装箱
Integer i1 =10;
Integer i2 = new Integer(10);
//自动拆箱
int i = i2;
//JDK5以前
int n1=100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueof(n1);
//通过这两种方式将 int ->Integer
int i = integer.intvalue();
//通过这种方法将 Integer-> int
//JDK5以后:
int n2=100;
Integer integer2 = n2;//自动装箱
int n3 = inetger2;//自动拆箱
}
}
故获取包装类的对象 不需要new 不需要调用方法 直接赋值即可
4.Integer成员方法
静态且返回类型是String
package com.itheimademo1.MathDemo2;
import java.util.Scanner;
public class IntegerTry {
public static void main(String[] args) {
int i =Integer.parseInt("123");
System.out.println(i);//123
//八种包装类中 除了Character都有对应的parseBoolean的方法
String str= "true";
boolean b = Boolean.parseBoolean(str);
System.out.println(b);
Scanner sc = new Scanner(System.in);
//nextInt next nextDouble 在接受数据时 遇到空格回车,制表符就停止了
//nextLine遇到回车才停止录入
String line = sc.nextLine();
System.out.println(line);
int a = Integer.parseInt(line);
}
}
5.包装类型和String类型相互转换
二、集合
1.集合体系结构
Collection 单列集合 添加数据的时候一次只能添加一个数据
Map 双列集合 添加数据的时候一次添加一对数据
Collection,List,Set都是接口
2.Collection:是单列集合的祖宗接口
a. 它的功能是全部单列集合都可以使用的
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.Collection;
public class demo1 {
public static void main(String[] args) {
// Collection 是一个接口 不能直接创建对象
//使用实现类ArrayList
Collection<String> coll = new ArrayList<>();
//是在Java中支持多态,就是父类的引用指向子类实例。
//(接口的实现也可以看作是 “继承” ,但与继承有区别)
//1.添加元素
//细节1:List 允许元素重复 故往List系列里面添加元素 永远是放回true
//细节2:如果往set系列的集合中添加数据,如果添加的元素存在 方法返回false 表示添加失败
coll.add("aaa");
coll.add("bbb");
System.out.println(coll);
//2.清空集合
//coll.clear();
//3.删除
//不能通过索引删除 只能通过元素的对象进行删除
//方法有一个返回值;删除成功返回true 删除失败返回false(如果要删除的元素不存在)
coll.remove("aaa");
//4.判断元素是否存在
//底层是依赖equals方法来判断是否存在
//所以,如果集合中存储的是自定义对象,也想通过该方法判断是否包含,那么在JavaBean类中,要重写equals方法
boolean re = coll.contains("bbb");//字符串 已经重写了equals方法 所以比较的值而不是地址
System.out.println(re);
//5.判断集合是否为空
Boolean re1 = coll.isEmpty();
System.out.println(re1);
//6.获取集合长度
int a = coll.size();
}
}
b.Collections工具类介绍
Collections 是一个操作 Set、List 和 Map 等集合的工具类
Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作
排序操作:(均为static方法)
1)reverse(List): 反转 List 中元素的顺序 2)shuffle(List):对 List 集合元素进行随机排序3)sort(list):根据元素的自然顺序对指定 List 集合元素按升序排序 4)sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序 5)swap(List,int, int):将指定 list 集合中的i处元素和j处元素进行交换
6)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素 7)Object max(Collection,Comparator):根据 Comparator 指定的顺序返回给定集合中的最大元素
8)Object min(Collection) 同上
9)int frequency(Colection,Object):返回指定集合中指定元素的出现次数
10)void copy(List dest,List src):将src中的内容复制到dest中
11)boolean replaceAll(List list,Object oldVal, Object newVal): 使用新值替换 List 对象的所有旧值
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Collection {
public static void main(String[] args) {
List list = new ArrayList();
list.add("to");
list.add("Smith");
list.add("kaqy");
list.add("abs");
list.add("to");
java.util.Collections.sort(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length() ;
}
});
System.out.println(list);
//按照字符串的长度大小排序
//输出:[to, abs, kaqy, Smith]
java.util.Collections.swap(list,0,1);
System.out.println(list);// //[abs, to, kaqy, Smith]
//返回自然排序最大的值
System.out.println(Collections.max(list));
//返回长度最大的元素
Object maxObject = Collections.max(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length();
}
});
System.out.println("长度最大的元素"+maxObject);
//返回长度最小的元素
Object minObject = Collections.max(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o2).length() - ((String)o1).length();
}
});
System.out.println("长度最小的元素"+minObject);
System.out.println("Tom出现的次数为="+Collections.frequency(list,"to"));
ArrayList dest = new ArrayList();
//拷贝之前需要先给dest赋值,大小和list.size一样
for(int i = 0;i<list.size();i++){
dest.add(" ");
}
//拷贝
Collections.copy(dest,list);
System.out.println("dest="+dest);
Collections.replaceAll(list,"to","tom");
//如果list中有to 就将其替换成tom
System.out.println(list);
}
}
3.Collection遍历方式
a.迭代器遍历
迭代器在Java中的类是Iterator 是集合专用的遍历方式
Collection集合获取迭代器:
Iterator<E> iterator() 返回迭代器对象,默认指向当前集合的0索引
Iterator中常用方法:
boolean hasNext() 判断当前位置是否有元素
E next() 获取当前位置的元素 并将迭代器对象向下移动一个位置
注意:
;如果当前位置没有元素,还要强行获取,则会报错NoSuchElementException;迭代器遍历完毕,指针不会复位 ; 循环中只能使用一次next方法; 迭代器遍历时,不能使用集合的方法进行增加或者删除(应该使用迭代器里面的方法删除)
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo2 {
public static void main(String[] args) {
//1.创建集合
Collection<String> coll = new ArrayList<>();
coll.add("abb");
coll.add("abb");
coll.add("abb");
coll.add("abb");
//2.获取迭代器对象
Iterator<String> it =coll.iterator();
//好比一个箭头 指向集合的0索引处
//3.利用循环获取元素
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
}
}
b.增强for遍历
增强for的底层就是迭代器,是为了简化代码书写的 所有的单列集合和数组才能用增强for进行遍历
格式:for(元素的数据类型 变量名:数组或者集合){}
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.Collection;
public class Demo3 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("12");
coll.add("123");
for(String s:coll){
System.out.println(s);
}//s是一个第三方变量 在循环过程中依次表示集合的每一个数据
//快速生成方式: 集合的名字+for 回车
for (String s : coll) {
s="111";//修改增强for中的变量不会改变集合中原本的数据
}
}
}
c.lambda表达式遍历
方法:forEach()
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Demo4 {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("12");
coll.add("23");
//1.匿名内部类实现
coll.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);//s 依次表示集合中每一个数据
}
});
// {
// @Override
// public void accept(String s) {
//
// }
// }这个没有名字的类实现了 Consumer这个接口 要重写接口里面的方法
//forEach底层原理:
//其实也会自己遍历集合 得到每一个元素
//把得到的每一个元素 传递给下面的accept方法
//2.lambda表达式
//() ->{}
coll.forEach((String s)->{
System.out.println(s);
});
}
}
4.LIst集合特有的方法以及遍历
a.Collection的方法List都继承了 List集合因为有索引,所以多了很多索引的操作方法
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.List;
public class ListDemo1 {
public static void main(String[] args) {
//1.创建一个集合
List<String> list = new ArrayList<>();
//2.添加元素
list.add("aaa");
list.add("bbb");
list.add("ccc");
//3.在指定的位置插入元素
list.add(1,"www");
System.out.println(list);//[aaa, www, bbb, ccc]
//4.删除指定位置处的元素 返回被删除的元素
//Collection中也有方法remove 在调用方法的时候,如果方法出现了重载现象
//那么就优先调用,实参和形参类型一致的那个方法!!!
//在Collection中的remove方法形参数的类型是一个对象 调用过程中会自动装箱
String remove = list.remove(0);
System.out.println(remove);//aaa
//5.修改指定处的元素 返回被修改的元素
String result = list.set(0,"mmm");
System.out.println(result);
//6.返回指定索引处的元素
String s= list.get(0);
System.out.println(s);
System.out.println(list);
}
}
b.list集合的遍历方式
迭代器遍历 列表迭代器遍历 增强for遍历 lambda表达式遍历 普通for循环遍历
package com.itheimademo1.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;
public class ListDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//1.迭代器
// Iterator<String> it = list.iterator();
// while (it.hasNext()){
// String str = it.next();
// System.out.println(str);
// }
//2.增强for
for (String s : list) {
System.out.println(s);
}
//3.lambda
list.forEach(s-> System.out.println(s));
//4.for
//size方法和get()方法
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
//5.列表迭代器
ListIterator<String> it = list.listIterator();
//在迭代器的基础上 额外添加了方法 可以添加元素
while (it.hasNext()){
String s = it.next();
if("bbb".equals(s)){
//list.add("qqq");//报错
it.add("qqq");
}
System.out.println(s);
}
}
}
5.集合和数组的对比
数组长度是固定的 集合长度是可变的
数组可以存储基本数据类型和引用数据类型;集合可以存储引用数据类型,存储基本数据类型的话,会将其转化为包装类;
6.List实现类
a.ArrayList学习:
创建集合:ArrayList<String> list = new ArrayList<>(); //泛型:限定集合中存储数据的类型
集合方法:Collection和List中的所有方法都可以使用
package com.itheimademo1.Collection;
import java.util.ArrayList;
public class ArrayListDemo1 {
public static void main(String[] args) {
//1.创建集合对象
//泛型:限定集合中存储数据的类型
ArrayList<String> list = new ArrayList<>();
//此时我们创建的是ArrayList对象 而ArrayList是java中以及写好的一个类
//这个类在底层做了一些处理打印对象不是地址而是集合存储数据的内容
//2.添加元素
boolean re = list.add("aaa");
System.out.println(re);
list.add("sss");
list.add("ddd");
//3.删除元素
boolean re1 = list.remove("aaa");
System.out.println(re1);
String s = list.remove(0);
System.out.println(s);
//4.修改元素
String s1 = list.set(0,"qqq");
//5.查询元素
String s2 = list.get(0);
//6.遍历
for (int i = 0; i < list.size(); i++) {
String s3 = list.get(i);
System.out.println(s3);
}
}
}
ArrayList:可以加入空值,并且可以加入多个空值 ;执行效率高但是线程不同步;基本等于Vector但是Vector是同步的
底层:
a.ArrayList中维护了一个Object类型的数组elementData ;
b.当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
c.如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为1.5倍。
b.LinkedList学习:
底层实现了双向链表和双端队列的特点,底层数据结构是双链表,查询慢,增删快;但是如果操作的是首尾元素,速度也会很快;可以添加任意元素(元素可以重复),包括null; 线程不安全
提供了许多首位操作的特有的API
底层:
a.LinkedList底层维护了一个双向链表.
b.LinkedList中维护了两个属性first和last分别指向 首节点和尾节点
c.每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表.
d.所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
c.Vector学习:
其底层也是一个对象数组,Vector是线程同步的,即线程安全的,Vector类的操作方法带有synchronized
三者比较:如果改查的操作比较多 选择ArrayList ;如果增删的操作比较的 选择LinkedList
7.Set接口和常用方法
基本介绍:无序(添加和取出的顺序不一样);不允许重复元素,最多只有一个null;Set实现类有HashSet,TreeSet,LinkedHashSet
常用方法:常用方法和Collection一样,遍历方式同Collection一样
package com.itheimademo1.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDeom1 {
public static void main(String[] args) {
Set set = new HashSet();
set.add("aaa");
set.add("bbb");
set.add("aaa");
set.add(null);
set.add(null);
//虽然添加的顺序与取出的顺序不一样 但是取出的顺序是固定的
System.out.println(set);
//1.遍历
Iterator it =set.iterator();
while (it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
//2.遍历
for(Object o:set){
System.out.println(o);
}
//3.不可用普通for循环
}
}
a.Set接口实现类——HashSet
HashSet实际上是HashMap 可以存放null,但是只能有一个;不能有重复的元素或者对象 (这句话真正的含义是什么)
package com.itheimademo1.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDeom1 {
public static void main(String[] args) {
Set set = new HashSet();
set.add("aaa");
set.add("bbb");
set.add("aaa");
set.add(null);
set.add(null);
//虽然添加的顺序与取出的顺序不一样 但是取出的顺序是固定的
set = new HashSet();
//HashSet不能添加重复的元素/对象
set.add("kuy");//添加成功
set.add("kuy");//添加失败
set.add(new Dog("tom"));//能加入
set.add(new Dog("tom"));//能加入 两个不同的对象。只是名字一样
set.add(new String("qq"));//能加入
set.add(new String("qq"));//加不了
//String重写了equals,比较的是内容,Dog没重写,
// 比较的是堆内存地址,前者true,后者false!!!!
System.out.println(set);
}
}
class Dog{
private String name;
public Dog(String name){
this.name = name;
}
}
底层:
1. HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)
2. 添加一个元素时,先得到hash值 -会转成-> 索引值 3.找到存储数据表table,看这个索引位置是否已经存放的有元素如果没有,直接加入如果有 , 调用 equals 比较,如果相同,就放弃添加,如果不相同,则添加到最后在Java8中,如果一条链表的元素个数到达 TREEIFY THRESHOLD(默认是8),并且table的大小>=MIN TREEIFY CAPACITY(默认64)就会进行树化(红黑树)
b.Set接口实现类——LinkedHashSet
LinkedHashSet 是HashSet 的子类;LinkedHashSet底层是一个 LinkedHashMap;维护了一个数组+双向链表;LinkedHashSet 根据元素的 hashcode 值来决定元素的存储位置,同时使用链表维护元素的次序(图),这使得元素看起来是以插入顺序保存的,;LinkedHashset 不允许添重复元素
!!!!一般覆盖时候,要重写hashcode,equals方法!!!
c.举个列子:
import java.util.LinkedHashSet;
import java.util.Objects;
@SuppressWarnings("all")
public class LiknedHashSet {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet();
// Set linkedHashSet1 = new LinkedHashSet(); 这个也行
linkedHashSet.add(new car ("奥迪",12222));
linkedHashSet.add(new car ("falali",122221));
linkedHashSet.add(new car ("baoshijie",12222));
linkedHashSet.add(new car ("奥迪",12222));
linkedHashSet.add(new car ("奥迪",12222));
//每一个都可以被添加进去 !!! 因为他们是不同的对象,他们的哈希值是不一样的
System.out.println(linkedHashSet);
//而为了让他们不能够被加进去 就需要重写hashcode方法和equals方法
//当 name和price相同时就返回相同的hashcode值
}
}
class car{
private String name;
private int price;
public car(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString(){
return "\ncar{" +
"name=" +name +'\'' +
",price="+ price +
"}";
}
//添加代码后 就不可以加入第二个奥迪了
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
car car = (car) o;
return price == car.price && Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
c.Set接口实现类——TreeSet
最大的特点就是可以排序 TreeSet的底层就是TreeMap
8.Map接口和常用方法
a.特点
1)Map与Collection并列存在。用于保存具有映射关系的数据:Kev_Value
2)Map 中的 key 和 value 可以是任何引用类型的数据,会封装到HashMap$Node对象中
3) Map 中的 key 不允许重复,原因和HashSet 一样,添加顺序和取出顺序不一致
import java.util.HashMap;
import java.util.Map;
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","AAA");
map.put("no2","AAA1");
map.put("no1","AAA2");//当有相同的key时,等价于替换
System.out.println(map);//{no2=AAA1, no1=AAA2}
}
}
4)Map 中的 value 可以重复
import java.util.HashMap;
import java.util.Map;
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","AAA");
map.put("no2","AAA1");
map.put("no3","AAA1");//当有相同的key时,等价于替换
System.out.println(map);//{no2=AAA1, no1=AAA, no3=AAA1}
}
}
5) Map 的key 可以为 null, value 也可以为nul ,注意 key 为null, 只能有一个(key不可以重复),value 为null ,可以多个
import java.util.HashMap;
import java.util.Map;
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","AAA");
map.put("no2","AAA1");
map.put("no3","AAA1");
map.put(null,null);
map.put(null,1);
map.put("no4",null);
map.put("no5",null);
System.out.println(map);//{no2=AAA1, null=1, no1=AAA, no4=null, no3=AAA1, no5=null}
}
}
6) 常用String类作为Map的 key
7) key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value
import java.util.HashMap;
import java.util.Map;
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no2","AAA1");
map.put("no3","AAA1");
map.put(new Object(),"11");
System.out.println(map.get("no1"));//通过get方法,传入key 会返回对应的value
}
}
b.Map接口 常用方法
1)put:添加
2)remove:根据键删除映射关系
3)get:根据键获取值
4)size:获取元素个数
5)isEmpty:判断个数是否为0
6)clear:清除
7)containsKey:查找键是否存在
c.Map的遍历
import java.util.*;
public class Map_ {
public static void main(String[] args) {
Map map = new HashMap();
map.put("no1","AAA");
map.put("no2","AAA1");
map.put("no3","AAA1");
map.put(new Object(),"11");
//1. 先取出key 通过key取出对应的value
Set keyset =map.keySet();
//a. 增强for
for(Object key:keyset){
System.out.println(key+"-"+map.get(key));
}
//b.迭代器
Iterator iterator = keyset.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
// System.out.println(key+"-"+map.get(key));
}
//2.取出所有的values
Collection values = map.values();
//a.增强for
for(Object value:values){
System.out.println(value);
}
//b.迭代器
Iterator it1 = values.iterator();
while (it1.hasNext()){
Object next = it1.next();
// System.out.println(value);
}
//3.通过EntrySet 获得k-v
Set entrySet =map.entrySet(); //EntrySet<Map.entry<k-v>>
//a.
for(Object entry :entrySet){
Map.Entry m = (Map.Entry) entry;
System.out.println(m.getKey()+ "-"+m.getValue());
}
//b.
Iterator it2 = entrySet.iterator();
while (it2.hasNext()){
Object next = it2.next();
Map.Entry m = (Map.Entry) entry ;
System.out.println(m.getKey()+ "-"+m.getValue());
}
}
}
d.Map接口的实现类——HaspMap
key 不能重复 但是value 可以重复
如果添加相同的key 会覆盖原来的key-value
与HashSet一样,不能保证映射的顺序 (底层是用hash 表的方式来存贮的)
HashMap 没有实现同步,因此线程是不安全的
e.Map接口的实现类——Hashtable
存放的元素是键值对;
hashtable 的键和值都不能为空 否则会抛出NullpointerException
hashTable 使用方法基本上和HashMap一样
hashTable 是线程安全的(synchronized),hashMap 是线程不安全的
f.Map接口的实现类——Properties
Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。他的使用特点和Hashtable类似
Properties 还可以用于 从 xxx.properties 文件中,加载数据到Properties类对象,并进行读取和修改