JAVAAPI(字符串与集合框架)

来源:互联网 发布:用例点估算法 编辑:程序博客网 时间:2024/06/05 06:17


API--String

String s1="abc";//s1是一个类类型变量,指向"abc"这个字符串对象。字符串"abc"最大的特点就是一旦被初始化就不可以被改变。但是s的指向可以改变。它可以改变指向哪个字符串。

s1.equals(s2)//String类复写了Object类中的equals方法,定义了自己特有的方法,该方法用于判断字符串是否相同。

String s1="abc";

String s2=new String"abc";//s1s2有什么区别?s1在内存中有一个对象。s2在内存中有2个对象。

String s1="abc";

String s3="abc";s1= =s3(因为s1s3指向同一个对象。)

String类适用于描述字符串事物。

那么它就提供了多个方法对字符串进行操作。

常见的操作有哪些?(以下字符串操作方法要求熟练运用,很重要

1,获取。

1.1 字符串中的包含的字符数,也就是字符串的长度。

int length():获取长度。

1.2 根据位置获取位置上某个字符。

char charAt(int index):当访问到的字符串中不存在的角标时会发生角标越界      

           StringIndexoutofBoundsException

1.3 根据字符获取该字符在字符串中位置。

int indexOf(int ch):返回的是ch在字符串中第一次出现的位置。

          如果没有找到,返回-1。 

int indexOf(int ch, int fromIndex) :fromIndex指定位置开始,获取ch在字符串中出现的位置。

int indexOf(String str):返回的是str在字符串中第一次出现的位置。

int indexOf(String str, int fromIndex) :fromIndex指定位置开始,获取str在字符串中出现的位置。

int lastIndexOf(int ch)(反向获取)

2,判断。

2.1 字符串中是否包含某一个子串。

boolean contains(str):

特殊之处:indexOf(str):可以索引str第一次出现位置,如果返回-1.表示该str不在字符串中存在。

所以,也可以用于对指定判断是否包含。

if(str.indexOf("aa")!=-1)

而且该方法即可以判断,又可以获取出现的位置。

2.2 字符中是否有内容。

boolean isEmpty(): 原理就是判断长度是否为0. 

2.3 字符串是否是以指定内容开头。

boolean startsWith(str);

2.4 字符串是否是以指定内容结尾。

boolean endsWith(str);

2.5 判断字符串内容是否相同。复写了Object类中的equals方法。

boolean equals(str);

2.6 判断内容是否相同,并忽略大小写。

boolean equalsIgnoreCase();

3,转换。

3.1 将字符数组转成字符串。

构造函数:String(char[])

  String(char[],offset,count):将字符数组中的一部分转成字符串。

静态方法:

static String copyValueOf(char[]);

static String copyValueOf(char[] data, int offset, int count) 

static String valueOf(char[]): 后续修改不会影响新创建的字符串。 

3.2 将字符串转成字符数组。**

char[] toCharArray():

3.3 将字节数组转成字符串。

String(byte[])

String(byte[],offset,count):将字节数组中的一部分转成字符串。

3.4 将字符串转成字节数组。

byte[]  getBytes():

3.5 将基本数据类型转成字符串。

static String valueOf(int)

static String valueOf(double)

//3+"";//String.valueOf(3);

特殊:字符串和字节数组在转换过程中,是可以指定编码表的。

4,替换

String replace(oldchar,newchar);

String s1 = s.replace('q','n');如果要替换的字符不存在,返回的还是原串。

也可以替换子字符串String s1 = s.replace("java","world");

5,切割

String[] split(regex);

   public static void  method_split()

{

String s = "zhagnsa,lisi,wangwu";

String[] arr  = s.split(",");

for(int x = 0; x<arr.length; x++)

{

sop(arr[x]);

}

}

6,子串。获取字符串中的一部分。

String substring(begin);

String substring(begin,end);

public static void method_sub()

{

String s = "abcdef";

sop(s.substring(2));//从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界异常。

sop(s.substring(2,4));//包含头,不包含尾。s.substring(0,s.length());获取整个字符串。

}

7,转换,去除空格,比较。

7.1 将字符串转成大写或则小写。

 String toUpperCase();

 String toLowerCase();

7.2 将字符串两端的多个空格去除。

String trim();

7.3 对两个字符串进行自然顺序的比较。

int compareTo(string);

public static void method_7()

{

String s = "    Hello Java     ";

sop(s.toLowerCase());

sop(s.toUpperCase());

sop(s.trim());

String s1 = "a1c";

String s2 = "aaa";

sop(s1.compareTo(s2));

}

功能要尽量细分独立出来,修改方便。

java包含头不包含尾。

1310API--StringBuffer(字符串缓冲区)

StringBuffer是一个容器。可以对字符串内容进行增删。

1,长度是可变化。2,可以操作多个数据类型。3,最终会通过toString方法变成字符串。

C create U update R read D delete

1,存储。

StringBuffer append():将指定数据作为参数添加到已有数据结尾处。

StringBuffer insert(index,数据):可以将数据插入到指定index位置。

2,删除。

StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end

StringBuffer deleteCharAt(index):删除指定位置的字符。

3,获取。

char charAt(int index) 

int indexOf(String str) 

int lastIndexOf(String str) 

int length() 

String substring(int start, int end) 

 

4,修改。

StringBuffer replace(start,end,string);

void setCharAt(int index, char ch) ;

5,反转。

StringBuffer reverse();

 

6

将缓冲区中指定数据存储到指定字符数组中。

void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 

JDK1.5 版本之后出现了StringBuilder.

StringBuffer是线程同步。

StringBuilder是线程不同步。

以后开发,建议使用StringBuilder(多线程建议使用StringBuffer

升级三个因素:

1,提高效率。

2,简化书写。

3,提高安全性。

基本数据类型对象包装类。

byte Byte

short Short

int Integer

long Long

boolean Boolean

float Float

double Double

char Character

基本数据类型对象包装类的最常见作用,

就是用于基本数据类型和字符串类型之间做转换

基本数据类型转成字符串。

基本数据类型+""

基本数据类型.toString(基本数据类型值);

如: Integer.toString(34);//34整数变成"34";

字符串转成基本数据类型。

xxx a = Xxx.parseXxx(String);

int a = Integer.parseInt("123");

double b = Double.parseDouble("12.23");

boolean b = Boolean.parseBoolean("true");

Integer i = new Integer("123");

int num = i.intValue();

十进制转成其他进制。

toBinaryString();

toHexString();

toOctalString();

其他进制转成十进制。

parseInt(string,radix);  parseInt(3c,16)  60

JDK1.5版本以后出现的新特性。

Integer x = new Integer(4);

Integer x = 4;//自动装箱。//new Integer(4)

x = x/* x.intValue() */ + 2;//x+2:x 进行自动拆箱。变成成了int类型。和2进行加法运算。

//再将和进行装箱赋给x

Integer a = 127;

Integer b = 127;

sop("a==b:"+(a==b));//结果为true。因为ab指向了同一个Integer对象。

//因为当数值在byte范围内,对于新特性,如果该数值已经存在,则不会在开辟新的空间。

 

每种类型集合的特点、底层结构了解清楚。

就是用父类引用指向子类对象,用多态增强扩展性。

为什么出现集合类?面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一 种方式。

数组和集合类同是容器,有何不同?数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

黑马程序员_API(字符串与集合框架) - zb83583047 - zb83583047的博客

 

Collection定义了集合框架的共性功能。

1,添加

add(e);

addAll(collection);

2,删除

remove(e);

removeAll(collection);   al1.removeAll(al2);

clear();

3,判断。

contains(e);

isEmpty();

4,获取

iterator();

size();

5,删除元素。

al.remove("java02");

al.clear();//清空集合。

6,判断元素。

sop("java03是否存在:"+al.contains("java03"));

sop("集合是否为空?"+al.isEmpty());

7,获取个数。集合长度。

sop("size:"+al.size());

8,获取交集。

retainAll();

al1.retainAll(al2);//取交集,al1中只会保留和al2中相同的元素。

9,集合变数组。

toArray();

1add方法的参数类型是Object。以便于接收任意类型对象。

2,集合中存储的都是对象的引用(地址)

Collection接口有两个子接口:

List(列表),Set(集)

List:可存放重复元素,元素存取是有序的。

Set:不可以存放重复元素,元素存取是无序的。

什么是迭代器呢?

其实就是集合的取出元素的方式。

如同抓娃娃游戏机中的夹子。

迭代器是取出方式,会直接访问集合中的元素。

所以将迭代器通过内部类的形式来进行描述。

通过容器的iterator()方法获取该内部类的对象。

al.add("java01");//add(Object obj);

al.add("java02");

al.add("java03");

al.add("java04");

Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。

while(it.hasNext())

{

sop(it.next());

}

Collection

|--List:元素是有序的,元素可以重复。因为该集合体系有索引。

|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。

|--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。

|--Set:元素是无序,元素不可以重复。

List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。

add(index,element);

addAll(index,Collection);

remove(index);

set(index,element);

get(index):

subList(from,to);

int indexOf(obj):获取指定元素的位置。

ListIterator listIterator();

List集合特有的迭代器。ListIteratorIterator的子接口。

在迭代时,不可以通过集合对象的方法操作集合中的元素。

因为会发生ConcurrentModificationException异常。

所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,

只能对元素进行判断,取出,删除的操作,

如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator

该接口只能通过List集合的listIterator方法获取。

Iterator it = al.iterator();//在迭代过程中,准备添加或者删除元素。

while(it.hasNext())

{

Object obj = it.next();

if(obj.equals("java02"))

//al.add("java008");错误

it.remove();//java02的引用从集合中删除了。

sop("obj="+obj);

}

sop(al);

*/

public static void main(String[] args) 

{

//演示列表迭代器。

ArrayList al = new ArrayList();

//添加元素

al.add("java01");

al.add("java02");

al.add("java03");

sop(al);

ListIterator li = al.listIterator();

//sop("hasPrevious():"+li.hasPrevious());逆向迭代。第一个前面为false

while(li.hasNext())

{

Object obj = li.next();

if(obj.equals("java02"))

//li.add("java009");

li.set("java006");

}

while(li.hasPrevious())

{

sop("pre::"+li.previous());

}

//sop("hasNext():"+li.hasNext());

//sop("hasPrevious():"+li.hasPrevious());

sop(al);

通过indexOf获取对象的位置。

  sop("index="+al.indexOf("java02"));

    al.subList(1,3);//或取子对象

sop("sub="+sub);

}

//获取所有元素。

for(int x=0; x<al.size(); x++)

{

System.out.println("al("+x+")="+al.get(x));

}

Iterator it = al.iterator();

while(it.hasNext())

{

sop("next:"+it.next());

}

ArrayList al = new ArrayList();

//添加元素

al.add("java01");

al.add("java02");

al.add("java03");

sop("原集合是:"+al);

//在指定位置添加元素。

al.add(1,"java09");

//删除指定位置的元素。

//al.remove(2);

//修改元素。

//al.set(2,"java007");

//通过角标获取元素。

sop("get(1):"+al.get(1));

sop(al);

LinkedList:特有方法:

addFirst();

addLast();

增加元素

getFirst();

getLast();

获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

removeFirst();

removeLast();

获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException

JDK1.6出现了替代方法。

offerFirst();

offerLast();

增加元素

peekFirst();

peekLast();

获取元素,但不删除元素。如果集合中没有元素,会返回null

pollFirst();

pollLast();

获取元素,但是元素被删除。如果集合中没有元素,会返回null

List集合判断元素是否相同,依据是元素的equals方法。

sop("remove 03 :"+al.remove(new Person("lisi03",33)));//remove方法底层也是依赖于元素的equals方法。

|--Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。

|--HashSet:底层数据结构是哈希表。是线程不安全的。不同步。

HashSet是如何保证元素唯一性的呢?

是通过元素的两个方法,hashCodeequals来完成。

如果元素的HashCode值相同,才会判断equals是否为true

如果元素的hashcode值不同,不会调用equals

注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcodeequals方法。

|--TreeSet:可以对Set集合中的元素进行排序。(自然排序)

底层数据结构是二叉树。

保证元素唯一性的依据:

compareTo方法return 0.

TreeSet排序的第一种方式:让元素自身具备比较性。

元素需要实现Comparable接口,覆盖compareTo方法。

也种方式也成为元素的自然顺序,或者叫做默认顺序。

TreeSet的第二种排序方式。

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

这时就需要让集合自身具备比较性。

在集合初始化时,就有了比较方式。

定义一个类,实现Comparator接口,覆盖compare方法。

定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

需求:

TreeSet集合中存储自定义对象学生。

想按照学生的年龄进行排序。

记住,排序时,当主要条件相同时,一定判断一下次要条件。

当元素自身不具备比较性,或者具备的比较性不是所需要的。

这时需要让容器自身具备比较性。

定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

定义一个类,实现Comparator接口,覆盖compare方法。

泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

好处

1.将运行时期出现问题ClassCastException,转移到了编译时期。

方便于程序员解决问题。让运行时问题减少,安全。

2,避免了强制转换麻烦。

泛型格式:通过<>来定义要操作的引用数据类型。

在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中很常见,

只要见到<>就要定义泛型。

其实<> 就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候,

早期定义Object来完成扩展。

现在定义泛型来完成扩展。

泛型类定义的泛型,在整个类中有效。

如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

特殊之处:

静态方法不可以访问类上定义的泛型。

如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

通配符。也可以理解为占位符。什么类都可以。

泛型的限定;用于泛型扩展用的。

? extends E: 可以接收E类型或者E的子类型。上限。

? super E: 可以接收E类型或者E的父类型。下限

MapCollection的区别

MapCollection在集合框架中属并列存在

Map存储的是键值对

Map存储元素使用put方法,Collection使用add方法

Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素

Map集合中键要保证唯一性

Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。

1,添加。

put(K key, V value) 

putAll(Map<? extends K,? extends V> m) 

2,删除。

clear() 

remove(Object key) 

3,判断。

containsValue(Object value) 

containsKey(Object key) 

isEmpty() 

4,获取。

get(Object key) 

size() 

values() 

entrySet() 

keySet() 

Map

|--Hashtable:底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的。jdk1.0.效率低。

|--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。

|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

Set很像。

其实大家,Set底层就是使用了Map集合。

添加元素,添加元素,如果出现添加时相同的键。那么后添加的值会覆盖原有键对应值。

put方法会返回被覆盖的值。返回以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。(如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。 

System.out.println("put:"+map.put("01","zhangsan1"));

System.out.println("put:"+map.put("01","wnagwu"));

System.out.println("get:"+map.get("04"));

可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。(如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。 

获取map集合中所有的值。

Collection<String> coll = map.values();

System.out.println(coll);

System.out.println(map);

map集合的两种取出方式:

1Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。所以可以以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。先获取map集合的所有键的Set集合,keySet();

Set<String> keySet = map.keySet();

//有了Set集合。就可以获取其迭代器。

Iterator<String> it = keySet.iterator();

while(it.hasNext())

{

String key = it.next();

//有了键可以通过map集合的get方法获取其对应的值。

String value  = map.get(key);

System.out.println("key:"+key+",value:"+value);

}

2Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,

而这个关系的数据类型就是:Map.Entry

Entry其实就是Map中的一个static内部接口。

为什么要定义在内部呢?

因为只有有了Map集合,有了键值对,才会有键值的映射关系。

关系属于Map集合中的一个内部事物。

而且该事物在直接访问Map集合中的元素。

//Map集合中的映射关系取出。存入到Set集合中。

Set<Map.Entry<String,String>> entrySet = map.entrySet();

Iterator<Map.Entry<String,String>> it = entrySet.iterator();

while(it.hasNext())

{

Map.Entry<String,String> me = it.next();

String key = me.getKey();

String value = me.getValue();

System.out.println(key+":"+value);

}

需求:对学生对象的年龄进行升序排序。

因为数据是以键值对形式存在的。

所以要使用可以排序的Map集合。TreeMapMapTest2

练习:

"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。

希望打印结果:a(1)c(2).....

通过结果发现,每一个字母都有对应的次数。

说明字母和次数之间都有映射关系。

注意了,当发现有映射关系时,可以选择map集合。

因为map集合中存放就是映射关系。

什么时候使用map集合呢?

当数据之间存在映射关系时,就要先想到map集合。

思路:

1,将字符串转换成字符数组。因为要对每一个字母进行操作。

2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。

3,遍历字符数组。

将每一个字母作为键去查map集合。

如果返回null,将该字母和1存入到map集合中。

如果返回不是null,说明该字母在map集合已经存在并有对应次数。

那么就获取该次数并进行自增。然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。

4,将map集合中的数据变成指定的字符串形式返回。

集合框架的工具类。

Collections:集合框架的工具类。里面定义的都是静态方法。

CollectionsCollection有什么区别?

Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。

它有两个常用的子接口,

List:对元素都有定义索引。有序的。可以重复元素。

Set:不可以重复元素。无序。

Collections是集合框架中的一个工具类。该类中的方法都是静态的

提供的方法中有可以对list集合进行排序,二分查找等方法。

通常常用的集合都是线程不安全的。因为要提高效率。

如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

Arrays:用于操作数组的工具类。

里面都是静态方法。

asList:将数组变成list集合

List<String> list = Arrays.asList(arr);

//把数组变成list集合有什么好处?

可以使用集合的思想和方法来操作数组中的元素。

注意:将数组变成集合,不可以使用集合的增删方法。

因为数组的长度是固定。如果你增删。那么会反生UnsupportedOperationException,

int[] nums = {2,4,5};

Integer[] nums = {2,4,5};

List<Integer> li = Arrays.asList(nums);

如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。

如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

集合变数组。

Collection接口中的toArray方法。

1,指定类型的数组到底要定义多长呢?

当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size

当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。

所以创建一个刚刚好的数组最优。

String[] arr = al.toArray(new String[al.size()]);

2,为什么要将集合变数组?

为了限定对元素的操作。不需要进行增删了。

高级for循环

格式:

for(数据类型 变量名 被遍历的集合(Collection)或者数组)

{

}

对集合进行遍历。

只能获取集合元素。但是不能对集合进行操作。

迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

传统for和高级for有什么区别呢?

高级for有一个局限性。必须有被遍历的目标。

建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。

for(Map.Entry<Integer,String> me : hm.entrySet())

{

System.out.println(me.getKey()+"------"+me.getValue());

}

JDK1.5版本出现的新特性。

方法的可变参数。

在使用时注意:可变参数一定要定义在参数列表最后面。

虽然少定义了多个方法。

但是每次都要定义一个数组。作为实际参数。

int[] arr = {3,4};

show(arr);

int[] arr1 = {2,3,4,5};

show(arr1);

可变参数。

其实就是上一种数组参数的简写形式。

不用每一次都手动的建立数组对象。

只要将要操作的元素作为参数传递即可。

隐式将这些参数封装成了数组。

public static void show(String str,int... arr)

{

System.out.println(arr.length);

}

当类名重名时,需要指定具体的包名。

当方法重名是,指定具备所属的对象或者类。

import java.util.*;

import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

import static java.util.Collections.*;

packa/Demo.class 

packb/Demo.class

import packa.*;

import packb.*;

import static  java.lang.System.*;//导入了System类中所有静态成员。

out.println("haha");

System:类中的方法和属性都是静态的。

out:标准输出,默认是控制台。

in:标准输入,默认是键盘。

描述系统一些信息。

获取系统属性信息:Properties getProperties();

Properties prop = System.getProperties();

因为PropertiesHashtable的子类,也就是Map集合的一个子类。

那么可以通过map的方法取出该集合中的元素。

该集合中存储都是字符串。没有泛型定义。

获取所有属性信息。

for(Object obj : prop.keySet())

{

String value = (String)prop.get(obj);

System.out.println(obj+"::"+value);

}

如何在系统中自定义一些特有信息呢?

System.setProperty("mykey","myvalue");

获取指定属性信息。

String value = System.getProperty("os.name");

System.out.println("value="+value);

可不可以在jvm启动时,动态加载一些属性信息呢?

String v = System.getProperty("haha");( -Dhaha=qqqqq 文件名)

System.out.println("v="+v);

Runtime对象

该类并没有提供构造函数。

说明不可以new对象。那么会直接想到该类中的方法都是静态的。

发现该类中还有非静态方法。

说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回值类型是本类类型。

由这个特点可以看出该类使用了单例设计模式完成。

该方式是static Runtime getRuntime();