双括号初始化java集合

双括号初始化集合

对于set、list、map集合,可以使用如下的方式进行初始化:

Set<String> set1 = new HashSet<String>(){{
	add("a");
	add("b");
}};

List<String> list1 = new LinkedList<String>() {{
	add("a");
	add("b");
	add("c");
}};

Map<String,String> map1 = new HashMap<String,String>(){{
	put("a","a");
	put("b","b");
	put("c","c");
}};

这里利用了内部类语法,这种方式比先new出对象然后再进行依次add要方便、简洁许多。该方法称之为“双括号初始化”(double brace initialization)。

1、语法解读

显然这是在HashMap的构造器中写了一个匿名内部类,这个匿名内部类含有一个实例初始化块,初始化块的内容是三个add()函数,向被初始化的this指向的HashMap中添加了三个元素。

2、性能问题

利用双大括号初始化集合从效率上来说可能不如标准的集合初始化步骤。原因在于使用双大括号初始化会导致内部类文件的产生,而这个过程就会影响代码的执行效率。

假设有一个Test1类,里面有1000个list,都是使用双括号初始化,编译后如下:

Test1$1.class
Test1$2.class
...
Test1$1000.class

二、其他初始化集合方式

下面是集中常见的集合初始化写法。

1、ImmutableList.of

guava提供的一种不可变集合的初始化,该方法返回一个不可变的集合。示例:

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");

places.add("test");//报错:java.lang.UnsupportedOperationException

2、Arrays.asList()

该方法返回的是一个list视图,不能对其进行修改。示例:

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

places.add("test");//报错:java.lang.UnsupportedOperationException

3、new ArrayList<String>(Arrays.asList())

对上面的一种改进,推荐使用这种方法。示例:

List<String> strings = new ArrayList<String>(Arrays.asList("foo", "bar", "baz"));

strings.add("test");

三、关于匿名内部类

匿名内部类也就是没有名字的内部类。正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写,但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

1、不使用匿名内部类来实现抽象方法

abstract class Person {
    public abstract void eat();
}
 
class Child extends Person {
    public void eat() {
        System.out.println("eat something");
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}

2、使用匿名内部类实现抽象方法

abstract class Person {
    public abstract void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

这种写法比较简洁。此外,匿名内部类还能用于接口上,例如:

interface Person {
    public void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现。最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。

Thread t = new Thread() {
	@Override
	public void run() {
		System.out.println("thread...");
	}
};
t.start();

Runnable r = new Runnable() {
	@Override
	public void run() {
		System.out.println("Runnable...");
	}
};
new Thread(r).start();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值