Lecture 5-Generics and Collections

Intended Learning Outcomes

  • To understand the advantage of being generic
  • To learn the syntax for generic class and generic method
  • To create generic class with multiple type parameters
  • To understand type inference(diamond and then)
  • To understand the architecture of Java Collections Framework
  • To apply the data structures and algorithms in JCF to solve
    problems

Non-Generic Type-A simple Box(only set get method) Class

  • what’s the problem of Box Class?
    Answer:
    • lots of redundant codes
    • more effort to maintain multiple implementations
    • Can’t be used to store custom type of objects
      - Due to lack of type information, there is no way to verify at compile time, how the class is used. One part of the code may place an Integer in the box and expect to get Integers out of it, while another part of the code may mistakenly pass in a String,resulting in a runtime error.
  • Some deal way
    • Polymorphism can deal previous problem(redundant)
    • Generic Type(to deal with the forth)
Public class Box<T>{
//T stands for"type"
	privata T t;
	public void set(T t){
		this.t=t;}
	public T get(){
		return t;
		}
}

Generic Type-a generic verision of the Box class

  1. Define
    A generic class is defined with the following format:
class name<T1, T2, ..., Tn>
 { /* ... */ }
  • The type parameter section, delimited by angle brackets (<>), follows the class name.
  • It specifies the type parameters (also called type variables) T1,T2, …, and Tn.
  • To update the Box class to use generics, you create a generic type declaration by changing the code “public class Box” to "public class Box <!>. This introduces the type variable,!:the type , that can be used anywhere inside the class.

请添加图片描述

  1. Advantage
    Answer:Generics add stability to code by making more of your bugs detectable at compile time.

Invoking and Instantiating a Generic Type

  • To reference the generic Box class from within your code, you must perform
    a generic type invocation, which replacesT with some concrete value:such as Integer: Box integerBox;
  • You can think of a generic type invocation as being similar to an ordinary method
    invocation, but instead of passing an argument to a method, you are passing a type argument — Integer in this case — to the Box class itself.
  • Like any other variable declaration, this code does not actually create a new Box object. It simply declares that integerBox will hold a reference to a
    “Box of Integer”, which is how Box is read.
  • An invocation of a generic type is generally known as a parameterized type.
  • To instantiate this class, use the new keyword, as usual, but place between the class name and the parenthesis:
Box<Integer> integerBox = new Box<Integer>();

Why use Generics?

The difference is that the inputs to formal parameters are values, while the
inputs to type parameters are types.
Code that uses generics has many benefits over non-generic code:

  1. Stronger type checks at compile time.(✅)
    A Java compiler applies strong type checking to generic code and issues
    errors if the code violates type safety. Fixing compile-time errors is easier
    than fixing runtime errors, which can be difficult to find.
    Generics add stability to code by making more of your bugs detectable at compile time.(✅)
  2. Elimination of casts
    消除了强转的步骤
  3. Enabling programmers to implement generic algorithms.
    By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.

The Diamond(只要编译器可以从上下文推断类型参数,就可以用一组空的类型参数<>替换调用generics所需的类型参数)

You can replace the type arguments required to invoke the constructor of a generic class with an empty set of type arguments (<>) as long as the compiler can
determine, or infer, the type arguments from the context.

  • This pair of angle brackets, <>, is called the diamond. For example, you can create an instance of Box with the following statement:
Box<Integer> integerBox = new Box<Integer>();//previous
Box<Integer> integerBox = new Box<>();//now

Multiple Type Parameters[belong to syntax]

For example, the generic OrderedPair class, which implements the generic Pair interface:
请添加图片描述
The following statements create two instantiations of the OrderedPari class:

pair<string,Integer> p1=new OrderedPair<string,Integer>("even",8);
pair<string,Integer> p2=new OrderedPair<string,Integer>("event",80);																															

The code, new OrderedPair<String, Integer>, instantiates K as a String and V as
an Integer. Therefore, the parameter types of OrderedPair’s constructor are String and Integer,respectively.

You can also substitute a type parameter (i.e., K or V) with a parameterized type
(i.e., List).
For example, using the OrderedPair<K,V> example:

OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));

Generic Methods–[type inference][syntax]

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter’s scope is limited to the method where it is declared.
Static and non-static generic methods are allowed, as well as generic class constructors.
The syntax for a generic method includes a type parameter,inside angle brackets, and appears before the method’s return type.

An example:
The Util class includes a generic method, compare, which compares
two Pair objects: the class itself not necessary be generic
请添加图片描述
The complete syntax for invoking this method would be:

pair<Interger,String>p1=new pair<>(1,"apple");
pair<Integer,String>p2=new pair<>(2,"pear");
boolean same=util.<Interger,String>compare(p1,p2);

The type has been explicitly provided, as shown in bold. Generally, this can
be left out and the compiler will infer the type (from the input arguments)
that is needed:

pair<Interger,String>p1=new pair<>(1,"apple");
pair<Integer,String>p2=new pair<>(2,"pear");
boolean same=util.compare(p1,p2);
  • This feature, known as type inference(like diamond), allows you to invoke a generic method as an ordinary method, without specifying a type between angle brackets.

Bounded Type(set a limitation of the type)

There may be times when you want to restrict the types that can be used as type arguments in a parameterized type.
For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
To declare a bounded type parameter, 1:list the type parameter’s name, followed by the extends keyword, followed by its upper bound, which in this
example is Number.(本例中上界为Number,表示只接受number和它的子类)Note that, in this context, extends is used in a general sense to mean either “extends” (as in classes) or “implements” (as in interfaces).

  • For multiple bounds:
     <T extends B1 & B2 & B3>
     where B1 is a class or interface and following bounds must be interface.请添加图片描述

Generics and inheritance and subtypes

You can perform a generic type invocation, passing Number as its type argument, and any subsequent invocation of add will be allowed if the argument is compatible with Number:

  • Now consider the following method:
 public void boxTest(Box<Number> n) { /* ... */ }
  1. What type of argument does it accept? By looking at its signature, you can see that it accepts a single argument whose type is Box. But what does that mean? Are you allowed to pass in Box or Box, as you might expect?
    - The answer is NO, because Box and Box are not subtypes of Box.
    • This is a common misunderstanding when it comes to programming with generics, but it is an important concept to learn.

Wildcards–(?)

In generic code, the question mark (?), called the wildcard, representing an unknown type, can be used to relax(broken) the restrictions on a variable.

  • The wildcard can be used in a variety of situations: as the type of a parameter, field,or local variable; sometimes as a return type (though it is better programming
    practice to be more specific).
  • The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.
    Consider the following method, printList where its goal is to print a list of any type but it fails to achieve .
    请添加图片描述
    请添加图片描述
    Answer:
    1. It prints only a list of Object instances. It cannot print List,
      List, List, and so on, because they are not subtypes of List. To write a generic printList method, use List<?> instead.
    2. When using wildcard, the type information is basically unknown, so there are two scenarios where an unbounded wildcard is a useful approach:
    • If you are writing a method that can be implemented by only using functionality provided in the Object class.
    • When the code is using methods in the generic class that don’t depend on the type parameter. For example, List.size() or List.clear().
      more flexible

The goal of JCF(Java collections Framework)

  1. The framework had to be high-performance. The implementations for the fundamental collections (dynamic arrays, linked lists, trees, and hashtables) are highly efficient.
  2. The framework had to allow different types of collections to work in a similar manner and with a high degree of interoperability.
  3. Extending and/or adapting a collection had to be easy.

All collections frameworks contain the following:

A collection framework is a unified architecture for representing and manipulating collections.

  1. Interfaces:
  2. Implementations, i.e., Classes:
    These are the concrete implementations of the collection interfaces. In essence, they are reusable data structures.
  3. Algorithms:
    请添加图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值