String
String声明为final 不可被继承
常用构造方法
String s="abc";
String s=new String("asdf")
String s=new String(byte数组)
String s=new String(byte数组,起始下标,长度)
String s=new String(char数组)
String s=new String(char数组,起始下标,长度)
byte [] bytes={98,97};//97是a 98是b String s1 = new String(bytes); System.out.println(s1); //ba char[] chars={'我','是','人'}; String s2=new String(chars); System.out.println("asdfgh".contains("as")); System.out.println("asdfgh".endsWith("gh")); System.out.println("aSDf".equalsIgnoreCase("asdf")); byte[] byt = "abc".getBytes(); for (int i = 0; i <byt.length ; i++) { System.out.print(byt[i]+" "); } System.out.println("abc".indexOf("bc")); //如果是-1则表示没有找到 System.out.println("abc".length()); System.out.println("asdfgsagd".lastIndexOf("sa")); System.out.println("asdfasdf".replace("asd", "aaa")); String[] split = "asdf-sdaf-dasgg".split("-"); System.out.println("asdf".startsWith("as"));//返回true或者false System.out.println("asdf".substring(0)); System.out.println("asdf".substring(0, 1));//a 左闭右开 char[] chars1 = "asdfas".toCharArray(); System.out.println(" sdfsdf sfsdf ".trim()); //去掉字符前后的空白中间的空白不去掉,参考账号输入时 String.valueOf(123); String.valueOf(true); System.out.println(new Person()); //调用valueOf里面的toString方法如果是个对象的话
StringBuffer 多线程安全
//创建一个初始化容量为16的byte数组 (字符串缓冲区对象)
StringBuffer stringbuffer=new StringBuffer();
stringBuffer.append("a")
stringBuffer.append (3.14)//底层是数组扩容会确保容量 如果超过容量byte数组满了,会调用system.arraycopy 他的声明不是final
底层是16位的byte数组
StringBuilder 多线程不安全
StringBuffer中的方法都有:synchronized关键字修饰。表示StringBuffer在多线程环境下运行是安全的。 StringBuiLder中的方法都没有:synchronized关键字修饰,表示StringBuilder在多线程环境下运行是不安全的。 StringBuffer是线程安全的。 StringBuilder是非线程安全的。
基本类型对象的8个包装类
Integer i=new Integer(123);// 基本数据类型->引用数据类型 装箱 float v = i.floatValue(); // 引用数据类型->基本数据类型 拆箱 long l = i.longValue(); //...基本数据类型中六种是Number类继承的,Number抽象类中有6种拆箱方法 Integer asd=new Integer("3"); System.out.println(asd); Float f=new Float(12.3); f.intValue(); Integer mm=100;//自动装箱 mm+100.sout 会自动转化成int int gg=mm; //自动拆箱 int a=Integer.parseInt("123"); String.valueOf() return String 输入:任意类型 Integer.valueOf() return Integer 输入:“”
Date
两个构造方法
1.Date->String
//表示当前时间 Date date=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String s1=sdf.format(date);
2.Date->String
//1970-01-01 00:00:00 001 Date date=new Date(1); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); //因为北京时间是东八区,差八个小时 String s1=sdf.format(date); //1970-01-01 08:00:00 001
String->Date
String s2="2008-08-08 08-59-59 599"; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); Date date=sdf.parse(date); System.out.println(date);//
System.currentTimeMills();
获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数
long a=System.currentTimeMills();
执行时间
long b=System.currentTimeMills();
b-a.sout
获取昨天的时间
Date date=new Date(System.currentTimeMillis()-1*24*60*60*1000); SimpleDateFormat sm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); System.out.println(sm.format(date));
DecimalFormat 数字格式
数字格式有哪些?
#代表任意数字
,代表千分位
.代表小数点
0代表不够时补0
java.text.DecimalFormat
DecimalFormat df=new DecimalFormat("###,###.##");
String a=df.format(33453.1245); //.format 返回的都是String字符串
保留4个小数位,不够时补0
DecimalFormat df=new DecimalFormat("###,###.0000");
BigDecimal
处理财务数据用BigDecimal,精度极高,是引用,不是基本数据类型
BigDecimal a=new BigDecimal(100);
BigDecimal b=new BigDecimal(200);
BigDecimal c=a.add(b);//.divide .substract
System.out.prinln(c);
Random
Random random=new Random();
int i=random.nextInt(101); // [0,100]
enum 枚举
表示可以一枚一枚列举出来
大于2种情况 枚举
2种情况 Boolean
高版本jdk 支持intString美剧
enum Result{
...,...,...
}
5.1、枚举是一种引用薮据类型。
5.2、枚举编译之后也是class文件。
5.3、枚举类型怎么定义? enum枚举类型名{ 枚举值,枚举值2,枚举值3}
5.4、当一个方法执行结果超过两种情况,并且是一枚一枚可以列举出来的时候,建议返回值类型设计为枚举类型。
Integer
128超过了127不在整数型常量池中,两个都是new出来的
Integer x=128; Integer y=128; System.out.println(x=y);
6、异常处理机制 6.1、java中异常的作用是:增强程序健壮性。6.2、 java中异常以类和对象的形式存在。
集合(多种数据结构)java.util包下
不能存储基本数据类型;
集合中任何时候存储的都是引用,指向的都是内存地址
list.add(100);这个是自动装箱;
单个方式存储元素是Collection
键值对的方式存储元素是Map
Collection
可以存放的是Object的子类型,
使用泛型后,只能存储某个具体的类型。
只能存放java对象的内存地址,不能存java对象。
常用方法
boolean add(Object o) 向集合中添加元素
int size() 获取元素的个数
void clear() 清空集合
boolean contains(Object o)判断集合中是否包含某个对象 底层调用equals
boolean remove(Object o) 删除这个集合中的某个元素 底层调用equals
boolean isEmpty() 判断集合是否为空
Object [] toArray() 把集合转换为数组
接口是抽象的,不能实例化。new Collection();错误 Collection c= new ArrayList(); c.add(1200);//自动装箱,实际上放入了一个对象的内存地址。Integer i=new Integer(1200); c.add(true); c.add("绿巨人") c.contains("绿巨人"); 返回true c.size();//获取元素的个数;
String 比较的是内容。已经重写过了
package collection; import java.util.ArrayList; import java.util.Collection; public class User { String name; public User(String name) { this.name = name; } @Override public boolean equals(Object o) { // if (this == o) return true; // if (o == null || getClass() != o.getClass()) return false; // User user = (User) o; // return Objects.equals(name, user.name); if(this==o) return true; if(o==null |!(o instanceof User)) return false; User user=(User)o; return user.name.equals(this.name); } } class Test1 { public static void main(String[] args) { User user = new User("j"); User user1 = new User("j"); Collection collection=new ArrayList(); collection.add(user); collection.contains(user1); //contains底层调用的是equals方法 因为User的equals的方法重写了 所以比较的是name, //Userequals没有重写之前比较的是内存地址; } }
HashSet 无序不可重复
迭代器
Iterator it=c.Iterator();
迭代器,相当于一个快照,Iterator it=c.Iterator();之后,迭代器迭代的时候会参照这个快照迭代。
会一直检查快照和原集合对比。
it.remove(1);会把快照中的1元素删掉,同时原集合中的1也会被清除。所以可以采用快照的remove方法
而 集合的remove方法只是把集合中的元素删掉,迭代器不知其变化,所以会出异常。
所以不能采用Collection的remove方法
只能采用Iterator中的remove方法
List
-
List集合存储元素的特点:有序可重复
有序:List集合中的元素有下标,从0开始,以1递增
2.List既然是Collection接口的子接口,那么肯定List接口有自己特色的方法:
以下只列出List接口特有的常用方法:
void add(int index,Object element)
List mylist=new ArrayList(); mylist.add("a");//默认向集合末尾添加元素 //king mylist.add("b"); mylist.add("c"); mylist.add("c"); mylist.add("d"); //index 从0开始,这个方法使用不多,因为ArrayList集合的底层是数组效率比较低。只比较适合末尾插入元素。 mylist.add(1,"KING"); Iterator it=mylist.iterator(); while (it.hasNext()){ Object o=it.next(); System.out.println(o); //a KING b c d }
Object get(int index)
是List集合特有的遍历方式
Set没有
Object o=mylist.get(1); o.sout//返回b for (int i=0;i<mylist.size();i++){ Object o=mylist.get(i); System.out.println(o); }
int indexOf(Object o)
//指定对象的第一次出现的索引 mylist.indexOf("c");//3
int lastIndexOF(Object o)
//指定对象最后一次出现的索引 mylist.lastIndexOF("c"); //4
void remove(int index)
//删除指定下标位置的元素 mylist.remove(0);//a没了
Object set(int index,Object element)
//修改指定位置的元素 如果没有指定位置的元素不能修改,会java.lang.IndexOutOfBoundsException异常
ArrayList
底层是Object[]数组 初始容量是10
是非线程安全的
//默认初始化容量是10 List list=new ArrayList(); //自定义容量是100 List list=new ArrayList(100); Collection c=new HashSet(); c.add(100); c.add(300); c.add(200); //把HashSet 转化为ArrayList List list=new ArrayList(c);
将ArrayList改为线程安全的
java.util.Colletions 集合工具类 java.util.Colletion 集合接口 Collections.synchronizedList(myList);
Collection.sort() 括号内只能是list
这里WuGui2后面忘记加了implements Comparable<WuGui2>
对List集合中元素排序,需要保证List集合中的元素实现了:Comparable接口
对Set集合的排序
Set<String> sets=new Set<>(); sets.add("s"); sets.add("a"); sets.add("b"); List<String> strings=new ArrayList<>(sets); Collections.sort(strings);
LinkedList
底层也是有下标的 .get 具体看List方法
LinkedList集合底层采用了双向链表数据结构
链表的优点 由于链表上的元素在空间存储上内存地址不连续 所以随机增删元素的时候不会有大量元素位移,因此随机增删效率较高。 在以后的开发中,如果遇到随机增删集合中的元素的业务比较多时,建议使用LinkedList 链表的缺点: 不能通过数学表达式计算查找元素的内存地址,每一次查找都是从头节点开始遍历,直到找到为止。所以 LinkedList集合检索/查找的效率较低。 ArrayList: 把检索发挥到极致(末尾添加元素效率还是很高 LinkedList:把随机增删发挥到极致 加元素一般都是末尾添加,所以Array List用的比LinkedList多 LinkedList没有初始化容量 最初链表中没有任何元素,first last 引用都是null
Vector
线程安全的
Set
无序不可重复
HashSet
String Integer 中的hashcode()和equals方法已经重写过了,所以不用再重写了
但是如果是自定义的类的话得重写方法,用idea生成就行。
底层是HahMap数据结构,初始化容量是16,扩容之后是原容量的2倍;
Set<String> strs=new HashSet<>(); strs.add("1"); strs.add("2"); strs.add("3"); strs.add("4"); strs.add("5"); 存取顺序不一样,放在HashSet集合中的元素实际上是放在HashMap的key部分了 for(String s:strs){ System.out.println(s); }
TreeSet
集合存储元素特点
-
无序不可重复,但是存储的元素可以自动按照大小顺序排序
-
无序指的是没有下标,存进去的顺序和取出来的顺序不同
Set<String> strs=new TreeSet<>(); add方法添加之后,foreach取出来是排好序的。
Map
无序不可重复
引用类型存的都是地址
MyClass.InnerClass 这个就是类名
举例 Set<Map.Entry<K,V>> entrySet()
V put(K key,V value) 向Map集合中添加键值对
Map<Integer,String> map=new HashMap<>(); map.put(1,"zhangsan"); map.put(2,"lisi"); map.put(3,"wangwu"); map.put(4,"zhaoliu");
contains方法底层都是equals进行比对的,所以自定义的类型需要重写equals方法
clear();清空所有
isEmpty();
V values(); 获取所有的value
K keySet 获取所有的Key
Set<Map.Entry<K,V>> entrySet()
Map.Entry<Integer, String> 这个相当于一个node 具体看源代码 这个对象有key value 属性可以取出来
Map<Integer,String> map=new HashMap<>(); map.put(1,"zhangsan"); map.put(2,"lisi"); map.put(3,"wangwu"); map.put(4, "zhaoliu"); //把Map集合全部转化为set集合 Set<Map.Entry<Integer, String>> set = map.entrySet(); //遍历set集合,每一次取出一个node Iterator<Map.Entry<Integer, String>> iterator = set.iterator(); while(iterator.hasNext()) { Map.Entry<Integer, String> node = iterator.next(); System.out.println(node.getKey()); System.out.println(node.getValue()); }
大数据量用这个foreach查找快,因为key和value都耦合在一起了。
用get比较慢 因为要在表中一个个查找。先拿到keyset 然后遍历key查找value
HashMap
底层是哈希表,数组,数组中放单向链表
hashcode()方法先把key值转化为哈希值hash
HashMap集合允许key为null,并且key重复的话覆盖
Map map=new HashMap(); map.put(null,null); map.put(null,100); map.get(null);//100
Hashtable
key和value都不能为空。不然会空指针异常。和HashMap相反。 Hashtable方法带有synchronnized:线程安全的。线程安全有其他的方案,这个Hashtable对线程的处理导致效率较低,现在使用较少了。 Hashtable和HashMap底层都是哈希表 Hashtable 初始化容量是11,默认加载因子是0.75f 扩容是元容量*2+1
Properties
Properties是一个Map集合继承与Hashtablekey和value都是String类型的
Properties被称为属性类对象;
Properties是线程安全的
Properties pro=new Properties(); //存方法,相当于调用map。put方法 pro.setProperty("url","jdbc")
通过key取value String driver=getProperty("url");
TreeMap
1.TreeSet 集合底层实际上是一个TreeMap
2.TreeMap 底层是一个二叉树
3.放在TreeSet集合中的元素,等同于放在TreeMap集合中的Key部分类比HashMap和HashSet
4.TreeSet集合中的元素:无序不可重复,但是可以按照元素大小顺序自动排序
称为:可排序集合。
TreeSet<String> ts= new TreeSet<>(); ts.add("b");ts.add("a");ts.add("c"); //a b c
需要去实现规则,Comparable 里的 CompareTo()方法,不然会类型错误
例子2
传参时有比较器的写法
或者匿名内部类的方式