集合
ArrayList默认存Object对象
ArrayList<Apple> apples = new ArrayList<Apple>();
左边<…>限制类型,左边的<…>可以不写,使用泛型在get()对象时,不用转型。同时可以用父类型当泛型参数
容器接口
-
List
特定的顺序保存一组元素set
元素不允许重复queue
集合一端插入对象 -
map
-
Collection
添加元素组
Arrays.asList()
:接受数组或者逗号分隔的元素列表
Collections.addAll()
:接受一个 Collection 对象,以及一个数组或是一个逗号分隔的列表
collection.addAll(Arrays.asList(moreInts));
迭代器 Iterator接口 单向运动
iterator()
方法要求集合返回一个 Iterator。next()
方法获得序列中的下一个元素。hasNext()
方法检查序列中是否还有元素。remove()
方法将迭代器最近返回的那个元素删除。
ListIterator 双向运动
-
set()
方法替换它访问过的最近一个元素 -
listIterator()
方法来生成指向 List 开头处的 ListIterator -
listIterator(n)
创建一个一开始就指向列表索引号为 n 的元素处的 ListIterator -
next()
方法获得序列中的下一个元素。 -
previous()
方法获得序列中的上一个元素。 -
hasPrevious()
-
hasNext()
fot-in 迭代 实现iterable接口
public Iterator<String> iterator() {
return new Iterator<String>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < words.length;
}
@Override
public String next() { return words[index++]; }
@Override
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
for-in 语句适用于数组或其它任何 Iterable ,但这并不意味着数组肯定也是个 Iterable
lambda 表达式
- 参数。
- 接着
->
,可视为“产出”。 ->
之后的内容都是方法体。- [1] 当只用一个参数,可以不需要括号
()
。 然而,这是一个特例。 - [2] 正常情况使用括号
()
包裹参数。 为了保持一致性,也可以使用括号()
包裹单个参数,虽然这种情况并不常见。 - [3] 如果没有参数,则必须使用括号
()
表示空参数列表。 - [4] 对于多个参数,将参数列表放在括号
()
中。
- [1] 当只用一个参数,可以不需要括号
static Body bod = h -> h + " No Parens!";
4.如果在 Lambda 表达式中确实需要多行,则必须将这些行放在花括号中。 在这种情况下,就需要使用 return。单行不行。
递归的lanbda表达
- 递归方法必须是
实例变量
或静态变量
fact = n -> n == 0 ? 1 : n * fact.call(n - 1);
方法应用
- 类名或对象名,后面跟
::
class Go {
static void go() {
System.out.println("Go::go()");
}
}
public class RunnableMethodReference {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
System.out.println("Anonymous");
}
}).start();
new Thread(
() -> System.out.println("lambda")
).start();
new Thread(Go::go).start();
}
}
输出结果:
Anonymous
lambda
Go::go()
未绑定的方法引用 非静态方法
class X {
String f() { return "X::f()"; }
}
interface MakeString {
String make();
}
interface TransformX {
String transform(X x);
}
public class UnboundMethodReference {
public static void main(String[] args) {
// MakeString ms = X::f; // [1]
TransformX sp = X::f;
X x = new X();
System.out.println(sp.transform(x)); // [2]
System.out.println(x.f()); // 同等效果
}
}
输出结果:
X::f()
X::f()
在调用前,传入原方法对象:
sp.transform(x)
将一个X类的对象传递给它,然后就以某种方式导致了对 x.f()
的调用。Java知道它必须拿到第一个参数
,该参数实际就是this
,并在其上调用方法。
This athis = new This();
twoargs.call2(athis, 11, 3.14);
构造函数引用
类名:: new
编译器可以检测并知道从哪个构造函数引用。
class Dog {
String name;
int age = -1; // For "unknown"
Dog() { name = "stray"; }
Dog(String nm) { name = nm; }
Dog(String nm, int yrs) { name = nm; age = yrs; }
}
interface MakeNoArgs {
Dog make();
}
interface Make1Arg {
Dog make(String nm);
}
interface Make2Args {
Dog make(String nm, int age);
}
public class CtorReference {
public static void main(String[] args) {
MakeNoArgs mna = Dog::new; // [1]
Make1Arg m1a = Dog::new; // [2]
Make2Args m2a = Dog::new; // [3]
Dog dn = mna.make();
Dog d1 = m1a.make("Comet");
Dog d2 = m2a.make("Ralph", 4);
}
}