java字符串,数组,集合框架重点

1.字符串的字面量是否自动生成一个字符串的变量?

String  str1  =  “abc”;

Sring  str2  =   new String (“abc”);

对于str1:Jvm在遇到双引号时会创建一个String对象,该String对象代表的值是abc,实际上,在创建该对象之前会在String对象池中搜索该字符串对象是否已经被创建,如果已经被创建,就直接返回一个字符串的引用,否则先创建再返回一个引用。

对于str2:需要的额外的工作是:会创建一个新的的string对象,通过new关键字来实现,并且返回一个引用给str2.

Str1==str2会返回false,因为指向的并不是同一个引用。

equals方法会进行字符序列的比较,则会返回true.

2.字符串对象池的作用是什么?

java虚拟机在启动的时候会实例化9个对象池,用来存储8种基本数据类型的包装类对象和String对象。

作用:避免频繁的创建和撤销对象而影响系统的性能。

例子:

 1 package test;
 2 
 3 import java.util.HashSet;
 4 
 5 class Dog{
 6 
 7 public Dog(String name, int age) {
 8 
 9 super();
10 
11 this.name = name;
12 
13 this.age = age;
14 
15 }
16 
17 private String name;
18 
19 private int age;
20 
21 private static HashSet<Dog> pool = new HashSet<Dog>();
22 
23 //使用对象池得到对象的方法
24 
25 public static Dog newInstance(String name,int age){
26 
27 for(Dog dog :pool){
28 
29 if(dog.name.equals(name)&&dog.age==age){
30 
31 return dog;
32 
33 }
34 
35 }
36 
37 //否则实例化一个新的dog
38 
39 Dog dog = new Dog(name,age);
40 
41 pool.add(dog);
42 
43 return dog;
44 
45 }
46 
47 }
48 
49 public class Main {
50 
51 public static void main(String[] args) {
52 
53 Dog dog1 = Dog.newInstance("xiaobai",1);
54 
55 Dog dog2 = Dog.newInstance("xiaobai", 1);
56 
57 Dog dog3 = new Dog("xiaobai",1);
58 
59 System.out.println(dog1==dog2);
60 
61 System.out.println(dog1==dog3);
62 
63 }
64 
65 }

 

 

本质理解:如果调用了new方法,则返回false,因为对象有了新的引用,如果没有调用new方法,就引用的是同一个对象,则返回true.

3.StringBufferStringBuilder的区别和应用场景?

javaString对象是不变性,只能被创建,但是不能改变其中的值。

 1 Demo1:
 2 
 3 package test;
 4 
 5 public class Main {
 6 
 7 public static void main(String[] args) {
 8 
 9 String a  = "a";
10 
11 String b  = "b";
12 
13 String c = "c";
14 
15 //采用这种方式,可以创建5个对象
16 
17 String abc = a+b+c;
18 
19 //使用stringbuffer可以解决性能问题
20 
21 //如果要保证是线程安全的,用stringbuilder
22 
23 StringBuffer sb = new StringBuffer();
24 
25 sb.append(a);
26 
27 sb.append(b);
28 
29 sb.append(c);
30 
31 }
32 
33 }
34 
35 Demo2:
36 
37 1 String s = "abcd";
38     2 s = s+1;
39     3 System.out.print(s);// result : abcd1

 

首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说 String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低。

 StringBufferStringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。

1 Demo3:
2 
3 1 String str = “This is only a” + “ simple” + “ test”;
4 2 StringBuffer builder = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

 

你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuffer居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

1 String str = “This is only a” + “ simple” + “test”;

 

其实就是:

String str = “This is only a simple test”;

所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:

string str2 = “This is only a”;

String str3 = “ simple”;

String str4 = “ test”;

String str1 = str2 +str3 + str4;

 

 

这时候JVM会规规矩矩的按照原来的方式去做。

Demo4:

StringBuilder与 StringBuffer

    StringBuilder:线程非安全的

    StringBuffer:线程安全的

  当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证 StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不 用StringBuffer的,就是速度的原因。

4.如何输出反转后的字符串?

三种方式的实现:

 1 package test;
 2 
 3 public class Main {
 4 
 5 public static void main(String[] args) {
 6 
 7 String s = "hello world";
 8 
 9 for(int i =s.length();i>0;i--){
10 
11 System.out.print(s.charAt(i-1));
12 
13 }
14 
15 System.out.println();
16 
17 System.out.println("--------------");
18 
19 char[] array = s.toCharArray();
20 
21 for(int i = array.length;i>0;i--){
22 
23 System.out.print(array[i-1]);
24 
25 }
26 
27 System.out.println();
28 
29 System.out.println("--------------");
30 
31         StringBuffer buff = new StringBuffer(s);
32 
33         System.out.println(buff.reverse().toString());
34 
35 }
36 
37 }

 

 

5.如何利用指定的字符集创造String对象?

不论是字符串的字面量,还是用String的构造方法创造字符串对象,都不会指定特定的字符集。平台的默认字符集是GBK或者GB2312,当我们用输入法输入中文后,这些中文的默认编码是GBK,但是JVM在编译的时候会按照unicode进行重新的编码。

利用特定的字符集进行编码:

 1 package test;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 
 5 public class Main {
 6 
 7 public static void main(String[] args) throws UnsupportedEncodingException {
 8 
 9 String s = "哈哈哈";
10 
11 String b = new String(s.getBytes(),"GBK");
12 
13 String c  = new String(s.getBytes(),"UTF-8");
14 
15 System.out.println(b);
16 
17 System.out.println(c);
18 
19  
20 
21 }
22 
23 }
24 
25 结果:哈哈哈  ??????

 

 

解释:实际上是对原有的字符串先转换为字节数组,然后用一种新的编码方法进行二次编码。

6.如何理解数组在java中作为一个类?

数组属于引用类型,每一个数组实例都是一个对象,这些对象同属于一个类。

java数组的实质是一个类,该类还保存了数据类型的信息。该类通过成员变量的形式保存数据,并且通过[],使用下标来访问这些数据,在处理基本数据类型时,数组保存的是变量的值,如果初始化,系统为之初始化为0;处理引用类型的数据时数组保存的书数据的引用,默认初始化为null.

7.new Object[5]语句是否创建了5个对象?

并没有创建5个对象,只是开辟了存放五个对象的内存空间。

Object[] objarr = new Object[5];

创建一个存储object的数组,长度为5,这5个元素的值都为null,只有为这些元素分别赋予了具体的对象,才会使得元素指定特定的引用。

 

8.二维数组的长度是否固定?

实质:先创建一个一维数组,然后该数组的元素再引用另外一个一维数组,在使用二维数组时,通过两个中括号来访问每一层维度的引用,直到访问到最后的数据。

二维数组的长度没必要去指定,他们的长度是各异的。

Int[][] arr = new int[3][];

第一维的长度是固定的为3,但是第二维的长度却不固定,可以变。

9.深拷贝和浅拷贝?

浅拷贝:只复制一个对象,对象内部存在的指向其他对象数组或者引用则不复制

深拷贝:对象,对象内部的引用均复制

10.什么是集合?

集合代表了一种底层的机构,用来拓展数组的功能,它的每一种形式代表了某一种数据结构。

Set:无序存放,不允许重复,可以存放不同类型的对象

List:有序存放,允许重复,可以存放不同类型的对象

SoretdSet:排好序列set

sortedMap:排好序列的map

注意:所有的集合实现类都只能存放对象,如果存放基本数据类型的数据,则需要使用包装类。

11.java中的迭代器是什么?

迭代器模式又称为游标模式,提供一种方法,访问一个容器对象中的元素,但是隐藏对象的内部细节。

实际上,迭代器就是一个接口Iterator,实现了该接口的类是可迭代类。

一个列子:

 1 package test;
 2 
 3 import java.util.ArrayList;
 4 
 5 import java.util.Iterator;
 6 
 7 import java.util.List;
 8 
 9 public class Main {
10 
11 public static void main(String[] args){
12 
13 List<String> list = new ArrayList<String>();
14 
15 list.add("hello");
16 
17 list.add("world");
18 
19 Iterator<String> it = list.iterator();
20 
21 //hasnext判断是否有下个元素,next()用于输出下一个元素
22 
23 while(it.hasNext()){
24 
25 System.out.println(it.next());
26 
27 }
28 
29 }
30 
31 }

 

12.java中的比较器是什么?

当用户自己自定义了一个类,这个类需要进行比较,这个时候就要使用到comparablecomparator接口。

Comparable进行比较类需要实现的接口,仅仅包含一个CompareTo()方法,(在类中需要重写该方法)只有一个参数,返回值类型为int型,如果该返回值大于0,表示本对象大于参数对象,如果小于0,表示本对象小于参数对象,等于0,则相等。

 

一个例子:

 1 package test;
 2 
 3 public class User implements Comparable{
 4 
 5 public User(String name, int age) {
 6 
 7 super();
 8 
 9 this.name = name;
10 
11 this.age = age;
12 
13 }
14 
15 public String getName() {
16 
17 return name;
18 
19 }
20 
21 public void setName(String name) {
22 
23 this.name = name;
24 
25 }
26 
27 public int getAge() {
28 
29 return age;
30 
31 }
32 
33 public void setAge(int age) {
34 
35 this.age = age;
36 
37 }
38 
39 @Override
40 
41 public int compareTo(Object o) {
42 
43 // TODO Auto-generated method stub
44 
45 return this.age-((User) o).getAge();
46 
47         //如果当前类的age大于参数的age 返回大于0的数
48 
49 //相等则返回0
50 
51 }
52 
53 private String name;
54 
55 private int age;
56 
57 }
58 
59 主函数测试:
60 
61 package test;
62 
63  
64 
65 public class Main {
66 
67 public static void main(String[] args){
68 
69     User   user1 = new User("hello",10);
70 
71     User  user2 = new User("wwww",20);
72 
73     if(user1.compareTo(user2)<0){
74 
75      System.out.println("user1's age is smaller");
76 
77     }else{
78 
79      System.out.println("equal");
80 
81     }
82 
83 }
84 
85 }

 

 

comparator也是一个接口,它的实现者被称为比较器,包含一个compare()方法,有两个参数,comparator不会被集合元素实现类所实现,而是单独实现或者是用匿名内部类实现。

一个例子:

首先自己定义一个比较器,用于比较特定的属性:

  1 package test;
  2 
  3 import java.util.Comparator;
  4 
  5 public class MyComparator implements Comparator {
  6 
  7  
  8 
  9 @Override
 10 
 11 public int compare(Object o1, Object o2) {
 12 
 13          User u1 = (User)o1;
 14 
 15          User u2 = (User)o2;
 16 
 17          return u1.getAge()-u2.getAge();
 18 
 19 }
 20 
 21 }
 22 
 23 实体类:
 24 
 25 package test;
 26 
 27 public class User{
 28 
 29 public User(String name, int age) {
 30 
 31 super();
 32 
 33 this.name = name;
 34 
 35 this.age = age;
 36 
 37 }
 38 
 39 public String getName() {
 40 
 41 return name;
 42 
 43 }
 44 
 45 public void setName(String name) {
 46 
 47 this.name = name;
 48 
 49 }
 50 
 51 public int getAge() {
 52 
 53 return age;
 54 
 55 }
 56 
 57 public void setAge(int age) {
 58 
 59 this.age = age;
 60 
 61 }
 62 
 63  
 64 
 65 private String name;
 66 
 67 private int age;
 68 
 69 }
 70 
 71 测试函数:
 72 
 73 package test;
 74 
 75 public class Main {
 76 
 77 public static void main(String[] args) {
 78 
 79 User user1 = new User("hello", 10);
 80 
 81 User user2 = new User("wwww", 20);
 82 
 83 int res;
 84 
 85     MyComparator comparator = new MyComparator();
 86 
 87     res= comparator.compare(user1, user2);
 88 
 89     if(res>0){
 90 
 91      System.out.println("user1's age bigger");
 92 
 93     }else if(res<0){
 94 
 95      System.out.println("user2's age bigger");
 96 
 97     }else{
 98 
 99      System.out.println("equal");
100 
101     }
102 
103 }
104 
105 }

 

13.Vectorarraylist的区别?

都是List接口的实现类,都代表链表形式的数据结构。

Vector是线程安全的,保证了线程安全,但是此时的执行效率会低一些,如果要求执行效率则使用arrayList.在使用方法上二者基本一样。

14.HashTableHashMap的区别?

二者在保存元素都是无序的。

1>HashTable的方法是线程同步的hashmap不能同步,在多线程的情况下要使用HashTable.

2>HashTable 不允许null值,keyvalue都不允许。HashMap允许null值,keyvalue都允许。

3>HashTable有一个contains方法,功能和containsvalue功能一样

4>HashTable使用Enumeration遍历,HashMap使用Iterator进行变量。

5>HashTable 中的hash数组的初始化大以及其增长方式不同

6>哈希值的使用不同,hashTable直接使用对象的HashCode,HashMap会重新计算哈希值。

如果没有要求是线程安全的,推荐使用hashMap,更符合java集合框架的设计思路。

15.集合使用泛型单来什么好处?

集合使用泛型后可以达到元素类型明确的目的,避免了手动类型转换的过程,同时也让开发者明确了容器保存的是什么类型的数据。这样,在每次从集合中取得的数据就不用每次取出一个进行类型的转换。需要注意的是,java的泛型是停在编译层的,jvm在对待泛型数据时,会依然把他们当成是object来处理,只是jvm会在底层帮助开发者完成类型的转换。

16.如何把集合对象中的元素进行排序?

vectorarraylist linkedlist本身不可以进行元素的排序。

可以使用java.utils.collections类下的sort方法进行排序。

如果列表中的全部是相同类型的数据元素,并且这个类实现了comparable接口,可以简单调用sort方法,如果没有实现comparator,就要传递一个comparator的实例作为第二个参数。

一个例子:

Student 类要实现Comparable接口,重写compareTo方法

  1 package test;
  2 
  3 public class Student implements Comparable<Student> {
  4 
  5 @Override
  6 
  7 public String toString() {
  8 
  9 return "Student [name=" + name + ", age=" + age + "]";
 10 
 11 }
 12 
 13 public String getName() {
 14 
 15 return name;
 16 
 17 }
 18 
 19 public void setName(String name) {
 20 
 21 this.name = name;
 22 
 23 }
 24 
 25 public int getAge() {
 26 
 27 return age;
 28 
 29 }
 30 
 31 public void setAge(int age) {
 32 
 33 this.age = age;
 34 
 35 }
 36 
 37 public Student(String name, int age) {
 38 
 39 super();
 40 
 41 this.name = name;
 42 
 43 this.age = age;
 44 
 45 }
 46 
 47 @Override
 48 
 49 public int compareTo(Student o) {
 50 
 51         if(this.age>o.age){
 52 
 53          return 1;
 54 
 55         }else if(this.age<o.age){
 56 
 57          return -1;
 58 
 59         }else{
 60 
 61          return 0;
 62 
 63         }
 64 
 65 }
 66 
 67 private String name;
 68 
 69 private int age;
 70 
 71  
 72 
 73 }
 74 
 75 测试类中按照三种方式去排序:
 76 
 77 package test;
 78 
 79 import java.util.ArrayList;
 80 
 81 import java.util.Collections;
 82 
 83 import java.util.Comparator;
 84 
 85 import java.util.Iterator;
 86 
 87 import java.util.List;
 88 
 89 public class Main {
 90 
 91 @SuppressWarnings("unchecked")
 92 
 93 public static void main(String[] args) {
 94 
 95 List<Student> list = new ArrayList<Student>();
 96 
 97 list.add(new Student("admin", 20));
 98 
 99 list.add(new Student("dddd", 30));
100 
101 list.add(new Student("wwww", 60));
102 
103 System.out.println("default order...");
104 
105 // 默认的顺序
106 
107 @SuppressWarnings("rawtypes")
108 
109 Iterator it = list.iterator();
110 
111 while (it.hasNext()) {
112 
113 System.out.println(it.next());
114 
115 }
116 
117 System.out.println("desc order...");
118 
119 // 降序排序
120 
121 @SuppressWarnings("rawtypes")
122 
123 Comparator comp = Collections.reverseOrder();
124 
125 Collections.sort(list, comp);
126 
127 @SuppressWarnings("rawtypes")
128 
129 Iterator it1 = list.iterator();
130 
131 while (it1.hasNext()) {
132 
133 System.out.println(it1.next());
134 
135 }
136 
137 System.out.println("by name order...");
138 
139  
140 
141 // 按照名字进行排序
142 
143 Collections.sort(list, new Comparator<Student>() {
144 
145 @Override
146 
147 public int compare(Student o1, Student o2) {
148 
149 return o1.getName().compareTo(o2.getName());
150 
151 }
152 
153 });
154 
155 Iterator it2 = list.iterator();
156 
157 while (it2.hasNext()) {
158 
159 System.out.println(it2.next());
160 
161 }
162 
163 }
164 
165 }

 

 

 

转载于:https://www.cnblogs.com/jiaqingshareing/p/5729990.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值