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对象。

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

例子:

 package test;

 import java.util.HashSet;

 class Dog{

 public Dog(String name, int age) {

 super();

 this.name = name;

 this.age = age;

 }

 private String name;

 private int age;

 private static HashSet<Dog> pool = new HashSet<Dog>();

 //使用对象池得到对象的方法

 public static Dog newInstance(String name,int age){

 for(Dog dog :pool){

 if(dog.name.equals(name)&&dog.age==age){

 return dog;

 }

 }

 //否则实例化一个新的dog

 Dog dog = new Dog(name,age);

 pool.add(dog);

 return dog;

 }

 }

 public class Main {

 public static void main(String[] args) {

 Dog dog1 = Dog.newInstance("xiaobai",1);

 Dog dog2 = Dog.newInstance("xiaobai", 1);

 Dog dog3 = new Dog("xiaobai",1);

 System.out.println(dog1==dog2);

 System.out.println(dog1==dog3);

 }

 }

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

3.StringBuffer和StringBuilder的区别和应用场景?

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

 Demo1:

 package test;

 public class Main {

 public static void main(String[] args) {

 String a  = "a";

 String b  = "b";

 String c = "c";

 //采用这种方式,可以创建5个对象

 String abc = a+b+c;

 //使用stringbuffer可以解决性能问题

 //如果要保证是线程安全的,用stringbuilder

 StringBuffer sb = new StringBuffer();

 sb.append(a);

 sb.append(b);

 sb.append(c);

 }

 }

 Demo2:

 1 String s = "abcd";
2 s = s+1;
3 System.out.print(s);// result : abcd1

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

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

 Demo3:

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

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

 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.如何输出反转后的字符串?

三种方式的实现:

 package test;

 public class Main {

 public static void main(String[] args) {

 String s = "hello world";

 for(int i =s.length();i>0;i--){

 System.out.print(s.charAt(i-1));

 }

 System.out.println();

 System.out.println("--------------");

 char[] array = s.toCharArray();

 for(int i = array.length;i>0;i--){

 System.out.print(array[i-1]);

 }

 System.out.println();

 System.out.println("--------------");

         StringBuffer buff = new StringBuffer(s);

         System.out.println(buff.reverse().toString());

 }

 }

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

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

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

 package test;

 import java.io.UnsupportedEncodingException;

 public class Main {

 public static void main(String[] args) throws UnsupportedEncodingException {

 String s = "哈哈哈";

 String b = new String(s.getBytes(),"GBK");

 String c  = new String(s.getBytes(),"UTF-8");

 System.out.println(b);

 System.out.println(c);

 }

 }

 结果:哈哈哈  ??????

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

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,实现了该接口的类是可迭代类。

一个列子:

 package test;

 import java.util.ArrayList;

 import java.util.Iterator;

 import java.util.List;

 public class Main {

 public static void main(String[] args){

 List<String> list = new ArrayList<String>();

 list.add("hello");

 list.add("world");

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

 //hasnext判断是否有下个元素,next()用于输出下一个元素

 while(it.hasNext()){

 System.out.println(it.next());

 }

 }

 }

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

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

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

一个例子:

 package test;

 public class User implements Comparable{

 public User(String name, int age) {

 super();

 this.name = name;

 this.age = age;

 }

 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;

 }

 @Override

 public int compareTo(Object o) {

 // TODO Auto-generated method stub

 return this.age-((User) o).getAge();

         //如果当前类的age大于参数的age 返回大于0的数

 //相等则返回0

 }

 private String name;

 private int age;

 }

 主函数测试:

 package test;

 public class Main {

 public static void main(String[] args){

     User   user1 = new User("hello",10);

     User  user2 = new User("wwww",20);

     if(user1.compareTo(user2)<0){

      System.out.println("user1's age is smaller");

     }else{

      System.out.println("equal");

     }

 }

 }

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

一个例子:

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

 package test;

 import java.util.Comparator;

 public class MyComparator implements Comparator {

 @Override

 public int compare(Object o1, Object o2) {

          User u1 = (User)o1;

          User u2 = (User)o2;

          return u1.getAge()-u2.getAge();

 }

 }

 实体类:

 package test;

 public class User{

 public User(String name, int age) {

 super();

 this.name = name;

 this.age = age;

 }

 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;

 }

 private String name;

 private int age;

 }

 测试函数:

 package test;

 public class Main {

 public static void main(String[] args) {

 User user1 = new User("hello", 10);

 User user2 = new User("wwww", 20);

 int res;

     MyComparator comparator = new MyComparator();

     res= comparator.compare(user1, user2);

     if(res>0){

      System.out.println("user1's age bigger");

     }else if(res<0){

      System.out.println("user2's age bigger");

     }else{

      System.out.println("equal");

     }

 }

 }

13.Vector和arraylist的区别?

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

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

14.HashTable和HashMap的区别?

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

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

2>HashTable 不允许null值,key和value都不允许。HashMap允许null值,key和value都允许。

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

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

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

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

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

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

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

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

vector和arraylist linkedlist本身不可以进行元素的排序。

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

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

一个例子:

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

 package test;

 public class Student implements Comparable<Student> {

 @Override

 public String toString() {

 return "Student [name=" + name + ", age=" + age + "]";

 }

 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 Student(String name, int age) {

 super();

 this.name = name;

 this.age = age;

 }

 @Override

 public int compareTo(Student o) {

         if(this.age>o.age){

          return 1;

         }else if(this.age<o.age){

          return -1;

         }else{

          return 0;

         }

 }

 private String name;

 private int age;

 }

 测试类中按照三种方式去排序:

 package test;

 import java.util.ArrayList;

 import java.util.Collections;

 import java.util.Comparator;

 import java.util.Iterator;

 import java.util.List;

 public class Main {

 @SuppressWarnings("unchecked")

 public static void main(String[] args) {

 List<Student> list = new ArrayList<Student>();

 list.add(new Student("admin", 20));

 list.add(new Student("dddd", 30));

 list.add(new Student("wwww", 60));

 System.out.println("default order...");

 // 默认的顺序

 @SuppressWarnings("rawtypes")

 Iterator it = list.iterator();

 while (it.hasNext()) {

 System.out.println(it.next());

 }

 System.out.println("desc order...");

 // 降序排序

 @SuppressWarnings("rawtypes")

 Comparator comp = Collections.reverseOrder();

 Collections.sort(list, comp);

 @SuppressWarnings("rawtypes")

 Iterator it1 = list.iterator();

 while (it1.hasNext()) {

 System.out.println(it1.next());

 }

 System.out.println("by name order...");

 // 按照名字进行排序

 Collections.sort(list, new Comparator<Student>() {

 @Override

 public int compare(Student o1, Student o2) {

 return o1.getName().compareTo(o2.getName());

 }

 });

 Iterator it2 = list.iterator();

 while (it2.hasNext()) {

 System.out.println(it2.next());

 }

 }

 }

最新文章

  1. BFC之浅析篇
  2. 十个节省时间的MySQL命令
  3. Idea_从Eclipse转Intellij IDEA
  4. Java Script基础(五) 内置对象Date
  5. iOS 从网络获取son并解析
  6. iOS开发-清理缓存功能的实现
  7. ecos编译redboot,vmware运行redboot,执行hello world(图形配置)
  8. display的table和cell外加table-layout:fixed等分布局,外加换行,word-wrap:break-word
  9. activemq的两种基本通信方式的使用及总结
  10. 建造者(Builder)模式
  11. CS231n 第一次作业KNN中本地CIFAR10数据集的载入
  12. uintAPi 之Renderer.material
  13. leetcode-algorithms 目录
  14. CPU与IRP的一些相关函数
  15. Jedis cluster集群初始化源码剖析
  16. 课程一(Neural Networks and Deep Learning),第三周(Shallow neural networks)—— 1、两层神经网络的单样本向量化表示与多样本向量化表示
  17. 浅析JavaBean
  18. SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读
  19. Install Python on Mac
  20. nodejs时间工具类

热门文章

  1. Delphi - cxGrid设定字段类型为CheckBox
  2. java学习之String类
  3. [Revit]开始:编写一个简单外部命令
  4. STL中set和multiset小结
  5. CodeForces 780 E Underground Lab
  6. lightoj 1382 - The Queue(树形dp)
  7. 271.已正确安装证书,但https显示连接不安全(此页面的部分内容不安全)
  8. SVN分支与主干合并
  9. STM32F 系列单片机 调试记录
  10. 为什么说 Java 程序员必须掌握 Spring Boot ?(转)