1. Inner class and anonymous inner class
The main difference between anonymous inner classes and lambda expressions is that
1. An anonymous inner class must implement all methods of the inherited class
2. Anonymous inner classes have an override flag when rewriting, but lambdas do not
3. The interface inherited by the lambda expression can only have one abstract method
In the process of using anonymous inner classes, we need to pay attention to the following points:
- 1. When using an anonymous inner class, we must inherit a class or implement an interface, but we cannot have both, and we can only inherit a class or implement an interface.
- 2. Constructors cannot be defined in anonymous inner classes.
- 3. There cannot be any static member variables and static methods in the anonymous inner class.
- 4. The anonymous inner class is a local inner class, so all the restrictions of the local inner class are also valid for the anonymous inner class.
- 5. An anonymous inner class cannot be abstract, it must implement all the abstract methods of the inherited class or implemented interface.
Anonymous inner class: A new class is defined inside the class
Classification of inner classes:
static inner class
instance inner class
local inner class
Actually use inner class to write the code, the readability is too poor
public interface Skill {<!-- --> void use(); // abstract method to release skills }
public class SkillImpl implements Skill {<!-- --> @Override public void use() {<!-- --> System.out.println("Biu~biu~biu~"); } }
public class Hero {<!-- --> private String name; // hero's name private Skill skill; // hero's skill public Hero() {<!-- --> } public Hero(String name, Skill skill) {<!-- --> this.name = name; this.skill = skill; } public void attack() {<!-- --> System.out.println("My name is " + name + ", start casting skills:"); skill.use(); // call the abstract method in the interface System.out.println("Skill cast completed."); } public String getName() {<!-- --> return name; } public void setName(String name) {<!-- --> this.name = name; } public Skill getSkill() {<!-- --> return skill; } public void setSkill(Skill skill) {<!-- --> this.skill = skill; } }
Use anonymous objects or anonymous inner classes to implement calls
public class DemoGame {<!-- --> public static void main(String[] args) {<!-- --> Hero hero = new Hero(); hero.setName("Ash"); // Set the hero's name // set hero skills hero.setSkill(new SkillImpl()); // Use a separately defined implementation class //You can also use an anonymous inner class instead Skill skill = new Skill() {<!-- --> @Override public void use() {<!-- --> System.out.println("Pia~pia~pia~"); } }; hero. setSkill(skill); }
Use both anonymous inner classes and anonymous objects
// Simplify further, using both anonymous inner classes and anonymous objects hero.setSkill(new Skill() {<!-- --> @Override public void use() {<!-- --> System.out.println("Biu~Pia~Biu~Pia~"); } }); hero. attack(); }
2. Reflection
The main principle of reflection is to call the corresponding constants and methods through characters: eg, unload the method name and variable name from the .properties file The way to get the Class object: 1. Class.forName("full class name"): Load the bytecode file into memory and return the Class object 2. Class name.class: obtained through the attribute class of the class name 3. Object.getClass(): The getClass() method is defined in the Object class.
Class object function: * Get function: 1. Get member variables * Field[] getFields() Get all public modified member variables * Field getField(String name) Get the member variable of the specified public modification * Field[] getDeclaredFields() Get all member variables, regardless of modifiers * Field getDeclaredField(String name) 2. Get constructors * Constructor<?>[] getConstructors() * Constructor<T> getConstructor(class<?>... parameterTypes) * Constructor<T> getDeclaredConstructor(class<?>... parameterTypes) * Constructor<?>[] getDeclaredConstructors() 3. Get member methods: * Method[] getMethods Get all public modified methods * Method getMethod(String name, class<?>... parameterTypes) * Method[] getDeclaredMethods() * Method getDeclaredMethod(String name, class<?>... parameterTypes) 4. Get the class name * String getName()
1. Get member variables
Person.classes omitted. . write it yourself
getFields()
public static void main(String[] args) throws Exception {<!-- --> //0. Get the Class object of Person Class personClass = Person. class; //1.Field[] getFields() gets all public modified member variables Field[] fields = personClass. getFields(); for (Field field : fields) {<!-- --> System.out.println(field); }
getField()
//2.Field getField(String name) Field a = personClass. getField("a"); //Get the value of member variable a Person p = new Person(); Object value = a. get(p); System.out.println(value); //Set the value of a a.set(p,"Zhang San"); System.out.println(p);
getDeclaredFields() & & getDeclaredField()
//Field[] getDeclaredFields(): Get all member variables, regardless of modifiers Field[] declaredFields = personClass. getDeclaredFields(); for (Field declaredField : declaredFields) {<!-- --> System.out.println(declaredField); } //Field getDeclaredField(String name) Field getd = personClass. getDeclaredField("d"); //Ignore security checks for access modifiers getd.setAccessible(true);//violent reflection Object value2 = getd.get(p);//Get the value of getd from the p object System.out.println(value2);
2. Get constructors
Constructor with parameters getConstructor(class>… parameterTypes)
public static void main(String[] args) throws Exception {<!-- --> //0. Get the Class object of Person Class personClass = Person. class; // Constructor with parameters //Constructor<T> getConstructor(class<?>... parameterTypes) Constructor constructor = personClass. getConstructor(String. class, int. class); //Create object Object person = constructor.newInstance("Zhang San", 23); System.out.println(person);
No-argument constructor getConstructor()
//Method 1 // no parameter constructor Constructor constructor1 = personClass. getConstructor(); System.out.println(constructor1); //Create object Object person1 = constructor1. newInstance(); System.out.println(person1); \t\t //Method 2 // Directly create a constructor with no parameters Object o = personClass. newInstance(); System.out.println(o);
3. Get member methods
Get method without parameters
public static void main(String[] args) throws Exception {<!-- --> //0. Get the Class object of Person Class personClass = Person. class; // method to get the specified name Method eat_method = personClass. getMethod("eat"); Person p = new Person(); //Execution method eat() method eat_method.invoke(p);
Get the parameterized method getMethod()
//Execute the crime with a String Method eat_method2 = personClass. getMethod("eat", String. class); //execution method eat_method2.invoke(p,"rice");
Get all public modified methods: getMethods()
//Get all public modification methods Method[] methods = personClass. getMethods(); for (Method method : methods) {<!-- --> System.out.println(method); String name = method. getName(); System.out.println(name); //method.setAccessible(true); }
4. Get the class name
//Get the class name String className = personClass. getName(); System.out.println(className);//cn.itcast.domain.Person
5. Test reflection, get the method through the Properties() object
The pro.properties file is created by itself
public class ReflectTest {<!-- --> public static void main(String[] args) throws Exception {<!-- --> //1. Load the configuration file //1.1 Create Properties object Properties pro = new Properties(); //1.2 Load the configuration file and convert it to a collection //1.2.1 Get the configuration file in the class directory ClassLoader classLoader = ReflectTest. class. getClassLoader(); InputStream is = classLoader. getResourceAsStream("pro. properties"); pro.load(is); //2. Get the data defined in the configuration file String className = pro. getProperty("className"); String methodName = pro. getProperty("methodName"); //3. Load this class into memory Class cls = Class. forName(className); //4. Create an object Object obj = cls. newInstance(); //5. Get the method object Method method = cls. getMethod(methodName); //6. Execution method method.invoke(obj); } }
compile successfully
No: Compilation failed (there is no abstract method in the interface and the number of abstract methods exceeds 1)
```java @FunctionalInterface public interface MyFunctionalInterface { //Define an abstract method public abstract void method(); }
public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{<!-- --> @Override public void method() {<!-- --> } }
3. Functional interface, generally used with Lambda expressions
(1) There must be an interface to use Lambda, and the interface has only one abstract method (that is, a functional interface).
(2) Lambda must be able to “context infer” (that is, infer the parameter type according to the context, which is also an advantage of Lambda, so that the parameter type can be omitted and more concise)
shortcoming:
(1) It is not easy to debug in debug mode;
(2) It is inconvenient to force type conversion in the lambda statement;
(3) You cannot modify the value outside forEach in foreach
(4) If it is not calculated in parallel, the calculation speed is not as good as the traditional for loop in many cases.
Functional interface: an interface with and only one abstract method is called a functional interface Of course, the interface can contain other methods (default, static, private) @FunctionalInterface annotation Function: It can detect whether the interface is a functional interface Yes: Compiled successfully No: Compilation failed (there is no abstract method in the interface and the number of abstract methods exceeds 1)
@FunctionalInterface public interface MyFunctionalInterface {<!-- --> //Define an abstract method public abstract void method(); }
public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{<!-- --> @Override public void method() {<!-- --> } }
1. The parameter of the method is an interface, so we can pass the anonymous inner class of the interface [the function of the anonymous inner is to reduce the writing of the implementation class]
public class Demo {<!-- --> //Define a method, the parameter uses the functional interface MyFunctionalInterface public static void show(MyFunctionalInterface myInter){<!-- --> myInter. method(); } public static void main(String[] args) {<!-- --> //Call the show method, the parameter of the method is an interface, so the implementation class object of the interface can be passed show(new MyFunctionalInterfaceImpl()); //Call the show method, the parameter of the method is an interface, so we can pass the anonymous inner class of the interface show(new MyFunctionalInterface() {<!-- --> @Override public void method() {<!-- --> System.out.println("Use the anonymous inner class to override the abstract method in the interface"); } }); } }
2. Use Lambda expressions to rewrite the method() method [() represents the method() method]
//Call the show method, the parameter of the method is a functional interface, so we can use Lambda expression show(()->{<!-- --> System.out.println("Use Lambda expression to rewrite the abstract method in the interface"); }); // Simplify the Lambda expression show(()-> System.out.println("Use Lambda expression to rewrite the abstract method in the interface"));
4. Detailed introduction of Stream
Detailed introduction of Stream All Collection collections can obtain stream through the default method of stream;
https://blog.csdn.net/qq_41821963/article/details/125364126
public class Demo02Stream {<!-- --> public static void main(String[] args) {<!-- --> //Create a List collection to store the name List<String> list = new ArrayList<>(); list.add("Zhang Wuji"); list.add("Zhou Zhiruo"); list.add("Zhao Min"); list.add("Zhang Qiang"); list.add("Zhang Sanfeng"); //Filter the elements in the list collection, as long as the elements starting with Zhang are stored in a new collection //Filter the listA collection, as long as the name length is 3, store it in a new collection //traverse listB collection list. stream() .filter(name->name.startsWith("Zhang")) .filter(name->name.length()==3) .forEach(System.out::println); } }
Convert collection to Stream
1. In the ArrayList collection
public class Demo01GetStream {<!-- --> public static void main(String[] args) {<!-- --> //Convert the collection to a Stream List<String> list = new ArrayList<>(); Stream<String> stream1 = list. stream(); } }
2. In the Set collection
Set<String> set = new HashSet<>(); Stream<String> stream2 = set. stream();
3. Acquisition of key and value in the HashMap collection of key-value pairs
Map<String,String> map = new HashMap<>(); // Get the key and store it in a Set collection Set<String> keySet = map. keySet(); Stream<String> stream3 = keySet. stream(); // Get the value and store it in a Collection Collection<String> values = map. values(); Stream<String> stream4 = values. stream();
4. Obtain key-value pairs (the mapping relationship between key and value entrySet)
//Get the key-value pair (the mapping relationship between key and value entrySet) Set<Map.Entry<String, String>> entries = map.entrySet(); Stream<Map.Entry<String, String>> stream5 = entries.stream();
5. Convert the array to Stream
//Convert the array to Stream Stream<Integer> stream6 = Stream.of(1, 2, 3, 4, 5); //Variable parameters can pass arrays Integer[] arr = {<!-- -->1,2,3,4,5}; Stream<Integer> stream7 = Stream.of(arr); String[] arr2 = {<!-- -->"a","bb","ccc"}; Stream<String> stream8 = Stream.of(arr2);
6. forEach
Common method in Stream _forEach void forEach(Consumer<? super T> action); This method receives a Consumer interface function, and will hand over each stream element to the function for processing. The Consumer interface is a consumption-type functional interface, which can pass Lambda expressions and consume data
according to
public static void main(String[] args) {<!-- --> //Get a Stream Stream<String> stream1 = Stream.of("Zhang San", "Li Si", "Wang Wu", "Zhao Liu", "Tian Qi"); //Use the method forEach in the Stream to traverse the data in the Stream /*stream.forEach((String name)->{ System.out.println(name); });*/ stream1.forEach(name->System.out.println(name)); }
7, filter
Common method in Stream _filter: used to filter data in Stream Stream<T> filter(Predicate<? super T> predicate); The parameter Predicate of the filter method is a functional interface, so Lambda expressions can be passed to filter the data Abstract method in Predicate: boolean test(T t);
Stream<String> stream = Stream.of("Zhang Sanfeng", "Zhang Cuishan", "Zhao Min", "Zhou Zhiruo", "Zhang Wuji"); //Filter the elements in the Stream, as long as the person surnamed Zhang Stream<String> stream2 = stream.filter((String name)->{<!-- -->return name.startsWith("Zhang");}); //traverse stream2 stream stream2.forEach(name->System.out.println(name));
7, map
Common method _map in Stream stream: used for type conversion
If you need to map elements from one stream to another stream, you can use the map method.
Stream map(Function super T, ? extends R> mapper);
This interface requires a Function function interface parameter, which can convert the T-type data in the current stream to another R-type stream.
Abstract method in Function:
R apply(T t);
//Get a Stream of String type Stream<String> stream = Stream.of("1", "2", "3", "4"); //Use the map method to convert (map) an integer of string type to an integer of type Integer stream.map((String s)->{<!-- --> return Integer. parseInt(s); }).forEach((i->System.out.println(i))); //shorthand stream.map(Integer::parseInt).forEach((System.out::println));
8, count
Common method _count in Stream: used to count the number of elements in Stream long count(); The count method is a terminal method, and the return value is an integer of type long So you can no longer call other methods in the Stream stream
ArrayList<Integer> list = new ArrayList<>(); list. add(1); list. add(2); list. add(3); list. add(4); list. add(5); list. add(6); list. add(7); Stream<Integer> stream = list. stream(); long count = stream. count(); System.out.println(count);//7
9, limit
Common method _limit in Stream: used to intercept elements in the stream The limit method can intercept the stream and only use the first n. Method signature: Stream<T> limit(long maxSize); The parameter is a long type, if the current length of the collection is greater than the parameter, it will be intercepted; otherwise, no operation will be performed The limit method is a delay method, which just intercepts the elements in the stream and returns a new stream, so you can continue to call other methods in the Stream stream
String[] arr = {<!-- -->"Beautiful Sheep", "Joyful", "Lazy", "Grey Wolf", "Red Wolf"}; Stream<String> stream = Stream.of(arr); //Use limit to intercept the elements in the Stream, as long as the first 3 elements Stream<String> stream2 = stream. limit(3); //traverse stream2 stream stream2.forEach(name->System.out.println(name));
10, skip
Common method _skip in Stream: used to skip elements If you want to skip the first few elements, you can use the skip method to get a new stream after interception: Stream<T> skip(long n); If the current length of the stream is greater than n, the first n streams are skipped; otherwise, an empty stream of length 0 will be obtained.
String[] arr = {<!-- -->"Beautiful Sheep", "Joyful", "Lazy", "Grey Wolf", "Red Wolf"}; Stream<String> stream = Stream.of(arr); //Use the skip method to skip the first 3 elements Stream<String> stream2 = stream.skip(3); //traverse stream2 stream stream2.forEach(name->System.out.println(name));
11, concat
Common methods in Stream stream_concat: used to combine streams together
If you have two streams and want to merge them into one stream, you can use the static method concat static Stream of the Stream interface
concat(Stream extends T> a, Stream extends T> b)
//Create a Stream stream Stream<String> stream1 = Stream.of("Zhang Sanfeng", "Zhang Cuishan", "Zhao Min", "Zhou Zhiruo", "Zhang Wuji"); //Get a Stream String[] arr = {<!-- -->"Beautiful Sheep","Joyful","Lazy","Grey Wolf","Red Wolf"}; Stream<String> stream2 = Stream.of(arr); // Combine the above two streams into one stream Stream<String> concat = Stream. concat(stream1, stream2); //traverse the concat stream concat.forEach(name->System.out.println(name));
Exercise: Collection element processing (Stream mode)
Replace the traditional for loop writing method in the previous question with the Stream streaming method.
The initial contents of the two collections are unchanged, as is the definition of the Person class.
public class Demo02StreamTest {<!-- --> public static void main(String[] args) {<!-- --> //first team ArrayList<String> one = new ArrayList<>(); one.add("Di Lieba"); one.add("Song Yuanqiao"); one.add("Su Xinghe"); one.add("Shi Potian"); one.add("Jade in the stone"); one.add("Lao Tzu"); one.add("Zhuangzi"); one.add("Hong Qigong"); //1. The first team only needs the name of the member whose name is 3 characters; store it in a new collection. //2. After the first team is screened, only the first 3 people are required; store it in a new collection. Stream<String> oneStream = one. stream(). filter(name -> name. length() == 3). limit(3); // second team ArrayList<String> two = new ArrayList<>(); two.add("Guli Nazha"); two.add("Zhang Wuji"); two.add("Zhao Liying"); two.add("Zhang Sanfeng"); two.add("Nicholas Zhao Si"); two.add("Zhang Tianai"); two.add("Zhang Ergou"); //3. The second team only needs the name of the member whose surname is Zhang; store it in a new collection. //4. After the second team is screened, don't want the first 2 people; store it in a new collection. Stream<String> twoStream = two.stream().filter(name -> name.startsWith("Zhang")).skip(2); //5. Merge the two teams into one team; store into a new collection. //6. Create a Person object based on the name; store it in a new collection. //7. Print the Person object information of the entire team. Stream.concat(oneStream, twoStream).map(name->new Person(name)).forEach(p->System.out.println(p)); Stream.concat(oneStream,twoStream).map(Person::new).forEach(System.out::println); } }
output:
Person{name=’Song Yuanqiao’}
Person{name=’Su Xinghe’}
Person{name=’Shi Potian’}
Person{name=’Zhang Tianai’}
Person{name=’Zhang Ergou’}