Java编程思想---枚举类型
Java编程思想—枚举类型
基本enum特性
调用enum的values()方法,可以遍历enum实例,values方法返回enum实例数组,而且该数组中的元素严格保持在enum中声明时的顺序
public enum Shrubbery {GROUND,CRAWLING,HANGING
}public class EnumClass {public static void main(String[] args) {for (Shrubbery s : Shrubbery.values()) {// ordinal方法返回一个int值 这是每个enum实例在声明时的次序 从 0 开始System.out.println(s + "orginal " + s.ordinal());System.out.println("_________________");// enum类实现了Comparable接口 所以具有compareTo方法System.out.println(s.compareTo(Shrubbery.CRAWLING ) + "");System.out.println("_________________");// 可以用 == 来比较enum实例 编译器会自动提供equal和hashcode方法System.out.println(s == Shrubbery.CRAWLING);System.out.println("_________________");// getDeclaringClass方法告诉我们所属的enum类System.out.println(s.getDeclaringClass());System.out.println("_________________");// name方法反复enum实例声明时的名字System.out.println(s.name());}for (String s:"jdddh hfhfj jfjkfjf".split(" ")) {// valueOf根据给定的名字返回相对应的enum实例Shrubbery shrubbery = Enum.valueOf(Shrubbery.class,s);System.out.println(shrubbery);}}
}
向enum中添加新的方法
可以向enum中添加方法,enum甚至可以有main()方法
public enum OzWitch {// 枚举类实例能够返回对自身的描述,可以提供一个构造器,专门负责处理这个额外的信息
// 然后添加一个方法,返回这个描述信息// 如果打算添加自己的方法,要在enum实例序列最后添加一个分号
// 同时你要先定义enum实例,再定义任何方法或者属性// Instances must be defined first, before methods:WEST("Miss Gulch, aka the Wicked Witch of the West"),NORTH("Glinda, the Good Witch of the North"),EAST("Wicked Witch of the East, wearer of the Ruby " +"Slippers, crushed by Dorothy’s house"),SOUTH("Good by inference, but missing");private String description;// Constructor must be package or private access:private OzWitch(String description) {this.description = description;}public String getDescription() { return description; }public static void main(String[] args) {for(OzWitch witch : OzWitch.values())print(witch + ": " + witch.getDescription());}}
覆盖enum方法
public enum SpaceShip {// 覆盖toString方法// 以我们想要的方式来生成字符串描述信息SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;public String toString() {String id = name();String lower = id.substring(1).toLowerCase();return id.charAt(0) + lower;}public static void main(String[] args) {for(SpaceShip s : values()) {System.out.println(s);}}}
Switch中使用enum
public enum Signal {GREEN, YELLOW, RED,}public class TrafficLight {// switch中使用enumSignal color = Signal.RED;public void change() {switch(color) {
// Note that you don’t have to say Signal.RED
// in the case statement:case RED: color = Signal.GREEN;break;case GREEN: color = Signal.YELLOW;break;case YELLOW: color = Signal.RED;break;}}public String toString() {return "The traffic light is " + color;}public static void main(String[] args) {TrafficLight t = new TrafficLight();for(int i = 0; i < 7; i++) {print(t);t.change();}}}
Values( )方法
public enum Explore {HERE, THERE}public class Reflection {// values方法从何而来?// 利用反射机制查看一下public static Set analyze(Class> enumClass) {print("----- Analyzing " + enumClass + " -----");print("Interfaces:");for(Type t : enumClass.getGenericInterfaces())print(t);print("Base: " + enumClass.getSuperclass());print("Methods: ");Set methods = new TreeSet();for(Method m : enumClass.getMethods())methods.add(m.getName());print(methods);return methods;}public static void main(String[] args) {Set exploreMethods = analyze(Explore.class);Set enumMethods = analyze(Enum.class);print("Explore.containsAll(Enum)? " +exploreMethods.containsAll(enumMethods));printnb("Explore.removeAll(Enum): ");exploreMethods.removeAll(enumMethods);print(exploreMethods);
// Decompile the code for the enum:
// OSExecute.command("javap Explore");}
}
实现,非继承
enum可以实现一个或多个接口
public enum CartoonCharacter implements Generator {SLAPPY, SPANKY, PUNCHY, SILLY, BOUNCY, NUTTY, BOB;private Random rand = new Random(47);public CartoonCharacter next() {return values()[rand.nextInt(values().length)];}}//public class EnumImplementation {
//
// public static void printNext(Generator rg) {
// System.out.print(rg.next() + ", ");
// }
// public static void main(String[] args) {Choose any instance:
// CartoonCharacter cc = CartoonCharacter.BOB;
// for(int i = 0; i < 10; i++)
// printNext(cc);
// }
//
//
//}
随机选取
利用泛型
public class Enums {// 随机选择// > 表示T是一个enum实例// Class作为参数我们就可以利用Class对象得到enum实例的数组了private static Random rand = new Random(47);public static > T random(Class ec) {return random(ec.getEnumConstants());}public static T random(T[] values) {return values[rand.nextInt(values.length)];}
}
random()方法示例:
public enum Activity {SITTING, LYING, STANDING, HOPPING,RUNNING, DODGING, JUMPING, FALLING, FLYING}public class RandomTest {public static void main(String[] args) {for(int i = 0; i < 20; i++)System.out.print(Enums.random(Activity.class) + " " + "\n");}
}
使用接口组织枚举
在一个接口内部,创建实现该接口的枚举
public interface Food {// 接口内部 创建实现该接口的枚举 以此将元素分组// 假设想用enum来表示不同的事物 同时还希望每个enum元素仍然保持food类型enum Appetizer implements Food {SALAD, SOUP, SPRING_ROLLS;}enum MainCourse implements Food {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}enum Dessert implements Food {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}// 对于eunum,实现接口是使其子类化的唯一办法
// 所以嵌入在food中的每个enum都实现了food接口public class TypeFod {public static void main(String[] args) {Food food = Food.Appetizer.SALAD;food = Food.MainCourse.LASAGNE;food = Food.Dessert.GELATO;food = Food.Coffee.CAPPUCCINO;}
}}
枚举中的枚举:
public enum Course {// 创建一个 枚举的枚举APPETIZER(Food.Appetizer.class),MAINCOURSE(Food.MainCourse.class),DESSERT(Food.Dessert.class),COFFEE(Food.Coffee.class);private Food[] values;private Course(Class extends Food> kind) {values = kind.getEnumConstants();}public Food randomSelection() {return Enums.random(values);}// 每一个Course的实例都将其对应的Class对象作为构造器的参数
// 通过getEnumConstants可以获取某个Food子类的所有enum实例
//}public class Meal {// 从每一个Course实例随机选择一个food 生成一份菜单public static void main(String[] args) {for (int i = 0; i < 5; i++) {for (Course course : Course.values()) {Food food = course.randomSelection();System.out.println(food);}System.out.println("-------------");}}
}
enum嵌套在一个enum:
public enum SecurityCategory {// 更加高效简洁的管理枚举的方法// 将一个enum 嵌套在另一个enum里面STOCK(Security.Stock.class), BOND(Security.Bond.class);Security[] values;SecurityCategory(Class extends Security> kind) {values = kind.getEnumConstants();}// Security接口是将其包含的enum组合成一个公共类型interface Security {enum Stock implements Security { SHORT, LONG, MARGIN }enum Bond implements Security { MUNICIPAL, JUNK }}public Security randomSelection() {return Enums.random(values);}public static void main(String[] args) {for(int i = 0; i < 10; i++) {SecurityCategory category =Enums.random(SecurityCategory.class);System.out.println(category + ": " +category.randomSelection());}}}
使用EnumSet代替标志
public enum AlarmPoints {// enumset的元素必须来自于一个enum// 下面的enum表示在一座大楼中// 警报传感器的安放位置STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,OFFICE4, BATHROOM, UTILITY, KITCHEN}public class EnumSets {// 用EnumSets来跟踪报警器的状态public static void main(String[] args) {EnumSet points =EnumSet.noneOf(AlarmPoints.class); // Empty setpoints.add(BATHROOM);print(points);points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));print(points);points = EnumSet.allOf(AlarmPoints.class);points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));print(points);points.removeAll(EnumSet.range(OFFICE1, OFFICE4));print(points);points = EnumSet.complementOf(points);print(points);}
}
enum超过64个元素?:
public class BigEnumSet {// EnumSet的基础是long,一个long值有64位 而一个enum实例只需要一位 bit 表示其是否存在// 也就是 在不超过一个long的表达能力的情况下 EnumSets可以应用于最多不超过64个元素的enum// 所以如果元素超过了64个会发生啥?enum Big { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10,A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21,A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32,A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43,A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54,A55, A56, A57, A58, A59, A60, A61, A62, A63, A64, A65,A66, A67, A68, A69, A70, A71, A72, A73, A74, A75 }public static void main(String[] args) {EnumSet bigEnumSet = EnumSet.allOf(Big.class);System.out.println(bigEnumSet);}
}
使用EnumMap
命令设计模式:
public interface Command {void action();}public class EnumMaps {// EnumMap 是一种特殊的Map 它要求其中的键必须来自于一个enumpublic static void main(String[] args) {EnumMap em =new EnumMap(AlarmPoints.class);em.put(KITCHEN, new Command() {public void action() { print("Kitchen fire!"); }});em.put(BATHROOM, new Command() {public void action() { print("Bathroom alert!"); }});for(Map.Entry e : em.entrySet()) {printnb(e.getKey() + ": ");e.getValue().action();}try { // If there’s no value for a particular key:em.get(UTILITY).action();} catch(Exception e) {print(e);}}
}
常量相关的方法
public enum ConstantSpecificMethod {// Java的enum有一个有趣的特性 允许你为enum实例编写方法 从而为每个enum实例赋予不同的行为// 要实现的话,你需要为enum定义一个或多个abstract方法 然后为每个enum实例实现该抽象方法DATE_TIME {String getInfo() {returnDateFormat.getDateInstance().format(new Date());}},CLASSPATH {String getInfo() {return System.getenv("CLASSPATH");}},VERSION {String getInfo() {return System.getProperty("java.version");}};abstract String getInfo();public static void main(String[] args) {for(ConstantSpecificMethod csm : values())System.out.println(csm.getInfo());}
}
但是我们并不能真的将enum实例作为一个类型去使用:
public enum LikeClasses {WINKEN { void behavior() { print("Behavior1"); } },BLINKEN { void behavior() { print("Behavior2"); } },NOD { void behavior() { print("Behavior3"); } };abstract void behavior();}public class NotClasses {// 编译器不允许我们将一个enum实例当做class类型// void f1(LikeClasses.WINKEN instance) {} // Nope
}
洗车的例子:
public class CarWash {// 关于洗车的例子// 洗车的时候提供一个选择菜单 每个选择对应一个不同的动作// 可以将一个常量相关的方法关联到一个选择上// 再使用一个enumset来保存客户的选择public enum Cycle {UNDERBODY {void action() { print("Spraying the underbody"); }},WHEELWASH {void action() { print("Washing the wheels"); }},PREWASH {void action() { print("Loosening the dirt"); }},BASIC {void action() { print("The basic wash"); }},HOTWAX {void action() { print("Applying hot wax"); }},RINSE {void action() { print("Rinsing"); }},BLOWDRY {void action() { print("Blowing dry"); }};abstract void action();}EnumSet cycles =EnumSet.of(Cycle.BASIC, Cycle.RINSE);public void add(Cycle cycle) {cycles.add(cycle);}public void washCar() {for(Cycle c : cycles)c.action();}public String toString() {return cycles.toString();}public static void main(String[] args) {CarWash wash = new CarWash();print(wash);wash.washCar();
// Order of addition is unimportant:wash.add(Cycle.BLOWDRY);wash.add(Cycle.BLOWDRY); // Duplicates ignoredwash.add(Cycle.RINSE);wash.add(Cycle.HOTWAX);print(wash);wash.washCar();}
}
覆盖常量相关方法:
public enum OverrideConstantSpecific {// 是否可以覆盖常量相关的方法呢? 当然可以NUT, BOLT,WASHER {void f() { print("Overridden method"); }};void f() { print("default behavior"); }public static void main(String[] args) {for(OverrideConstantSpecific ocs : values()) {printnb(ocs + ": ");ocs.f();}}}
使用enum的责任链
public class Mail {// 责任链设计模式// 程序员以不同的方式来解决一个问题 然后将它们链接到一起// 以一个邮局的模型为例,邮局需要以尽可能通用的方式来处理每一封邮件,并且要不断尝试处理邮件 直到该邮件被认定为一封死信// 邮件的每个关键特征都可以用enum来表示 程序将随机生成Mail对象// The NO’s lower the probability of random selection:enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4}enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6}enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5}GeneralDelivery generalDelivery;Scannability scannability;Readability readability;Address address;ReturnAddress returnAddress;static long counter = 0;long id = counter++;public String toString() { return "Mail " + id; }public String details() {return toString() +", General Delivery: " + generalDelivery +", Address Scanability: " + scannability +", Address Readability: " + readability +", Address Address: " + address +", Return address: " + returnAddress;}// Generate test Mail:
// 负责随机的创建用于测试的邮件public static Mail randomMail() {Mail m = new Mail();m.generalDelivery= Enums.random(GeneralDelivery.class);m.scannability = Enums.random(Scannability.class);m.readability = Enums.random(Readability.class);m.address = Enums.random(Address.class);m.returnAddress = Enums.random(ReturnAddress.class);return m;}public static Iterable generator(final int count) {return new Iterable() {int n = count;public Iterator iterator() {return new Iterator() {public boolean hasNext() { return n-- > 0; }public Mail next() { return randomMail(); }public void remove() { // Not implementedthrow new UnsupportedOperationException();}};}};}}public class PostOffice {enum MailHandler {GENERAL_DELIVERY {boolean handle(Mail m) {switch(m.generalDelivery) {case YES:print("Using general delivery for " + m);return true;default: return false;}}},MACHINE_SCAN {boolean handle(Mail m) {switch(m.scannability) {case UNSCANNABLE: return false;default:switch(m.address) {case INCORRECT: return false;default:print("Delivering "+ m + " automatically");return true;}}}},VISUAL_INSPECTION {boolean handle(Mail m) {switch(m.readability) {case ILLEGIBLE: return false;default:switch(m.address) {case INCORRECT: return false;default:print("Delivering " + m + " normally");return true;}}}},RETURN_TO_SENDER {boolean handle(Mail m) {switch(m.returnAddress) {case MISSING: return false;default:print("Returning " + m + " to sender");return true;}}};abstract boolean handle(Mail m);}static void handle(Mail m) {for(MailHandler handler : MailHandler.values())if(handler.handle(m))return;print(m + " is a dead letter");}public static void main(String[] args) {for(Mail mail : Mail.generator(10)) {print(mail.details());handle(mail);print("*****");}}
}
使用enum的状态机
public enum Input {NICKEL(5), DIME(10), QUARTER(25), DOLLAR(100),TOOTHPASTE(200), CHIPS(75), SODA(100), SOAP(50),ABORT_TRANSACTION {public int amount() { // Disallowthrow new RuntimeException("ABORT.amount()");}},STOP { // This must be the last instance.public int amount() { // Disallowthrow new RuntimeException("SHUT_DOWN.amount()");}};int value; // In centsInput(int value) { this.value = value; }Input() {}int amount() { return value; }; // In centsstatic Random rand = new Random(47);public static Input randomSelection() {
// Don’t include STOP:return values()[rand.nextInt(values().length - 1)];}}public enum Category {MONEY(NICKEL, DIME, QUARTER, DOLLAR),ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),QUIT_TRANSACTION(ABORT_TRANSACTION),SHUT_DOWN(STOP);private Input[] values;Category(Input... types) { values = types; }private static EnumMap categories =new EnumMap(Input.class);static {for(Category c : Category.class.getEnumConstants())for(Input type : c.values)categories.put(type, c);}public static Category categorize(Input input) {return categories.get(input);}
}public class VendingMachine {private static State state = State.RESTING;private static int amount = 0;private static Input selection = null;enum StateDuration { TRANSIENT } // Tagging enumenum State {RESTING {void next(Input input) {switch(Category.categorize(input)) {case MONEY:amount += input.amount();state = ADDING_MONEY;break;case SHUT_DOWN:state = TERMINAL;default:}}},ADDING_MONEY {void next(Input input) {switch(Category.categorize(input)) {case MONEY:amount += input.amount();break;case ITEM_SELECTION:selection = input;if(amount < selection.amount())print("Insufficient money for " + selection);else state = DISPENSING;break;case QUIT_TRANSACTION:state = GIVING_CHANGE;break;case SHUT_DOWN:state = TERMINAL;default:}}},DISPENSING(StateDuration.TRANSIENT) {void next() {print("here is your " + selection);amount -= selection.amount();state = GIVING_CHANGE;}},GIVING_CHANGE(StateDuration.TRANSIENT) {void next() {if(amount > 0) {print("Your change: " + amount);amount = 0;}state = RESTING;}},TERMINAL { void output() { print("Halted"); } };private boolean isTransient = false;State() {}State(StateDuration trans) { isTransient = true; }void next(Input input) {throw new RuntimeException("Only call " +"next(Input input) for non-transient states");}void next() {throw new RuntimeException("Only call next() for " +"StateDuration.TRANSIENT states");}void output() { print(amount); }}static void run(Generator gen) {while(state != State.TERMINAL) {state.next(gen.next());while(state.isTransient)state.next();state.output();}}public static void main(String[] args) {Generator gen = new RandomInputGenerator();if(args.length == 1)gen = new FileInputGenerator(args[0]);run(gen);}
}
多路分发
“剪刀石头布游戏”
public enum Outcome {// 结果WIN,LOSE,DRAW
}
public class Paper implements Item{// 对应剪刀石头布 中的 布@Overridepublic Outcome compete(Item item) {return item.eval(this);}// 一样肯定平局@Overridepublic Outcome eval(Paper paper) {return Outcome.DRAW;}//@Overridepublic Outcome eval(Scissors scissors) {return Outcome.WIN;}@Overridepublic Outcome eval(Rock rock) {return Outcome.LOSE;}@Overridepublic String toString() {return "Paper{}";}
}public class Rock implements Item{// 对应剪刀石头布 中的 石头@Overridepublic Outcome compete(Item item) {return item.eval(this);}@Overridepublic Outcome eval(Paper paper) {return Outcome.WIN;}@Overridepublic Outcome eval(Scissors scissors) {return Outcome.LOSE;}@Overridepublic Outcome eval(Rock rock) {return Outcome.DRAW;}@Overridepublic String toString() {return "Rock{}";}
}public class Scissors implements Item{// // 对应剪刀石头布 中的 剪刀@Overridepublic Outcome compete(Item item) {return item.eval(this);}@Overridepublic Outcome eval(Paper paper) {return Outcome.LOSE;}@Overridepublic Outcome eval(Scissors scissors) {return Outcome.DRAW;}@Overridepublic Outcome eval(Rock rock) {return Outcome.WIN;}@Overridepublic String toString() {return "Scissors{}";}
}public interface Item {Outcome compete(Item item);Outcome eval(Paper paper);Outcome eval(Scissors scissors);Outcome eval(Rock rock);
}public class RoShamBo1 {static final int SIZE = 20;private static Random random = new Random(47);// 随机出 剪刀石头布public static Item newItem(){switch (random.nextInt(3)){default:case 0: return new Scissors();case 1: return new Paper();case 2: return new Rock();}}public static void match(Item a,Item b){System.out.println(a + "vs " + b + ": " + a.compete(b));}public static void main(String[] args) {// 随机比赛 20次for (int i = 0; i < SIZE; i++) {match(newItem(),newItem());}}
}
使用enum分发
public enum RoShamBo2 implements Competitor{// 使用enum分发PAPER(DRAW, LOSE, WIN),SCISSORS(WIN, DRAW, LOSE),ROCK(LOSE, WIN, DRAW);private Outcome vPAPER, vSCISSORS, vROCK;RoShamBo2(Outcome paper,Outcome scissors,Outcome rock) {this.vPAPER = paper;this.vSCISSORS = scissors;this.vROCK = rock;}public Outcome compete(RoShamBo2 it) {switch(it) {default:case PAPER: return vPAPER;case SCISSORS: return vSCISSORS;case ROCK: return vROCK;}}public static void main(String[] args) {RoShamBo.play(RoShamBo2.class, 20);}}
使用常量相关的方法
public enum RoShamBo3 implements Competitor {// 使用常量相关的方法PAPER {public Outcome compete(RoShamBo3 it) {switch(it) {default: // To placate the compilercase PAPER: return DRAW;case SCISSORS: return LOSE;case ROCK: return WIN;}}},SCISSORS {public Outcome compete(RoShamBo3 it) {switch(it) {default:case PAPER: return WIN;case SCISSORS: return DRAW;case ROCK: return LOSE;}}},ROCK {public Outcome compete(RoShamBo3 it) {switch(it) {default:case PAPER: return LOSE;case SCISSORS: return WIN;case ROCK: return DRAW;}}};public abstract Outcome compete(RoShamBo3 it);public static void main(String[] args) {RoShamBo.play(RoShamBo3.class, 20);}
}
简化:
public enum RoShamBo4 implements Competitor {ROCK {public Outcome compete(RoShamBo4 opponent) {return compete(SCISSORS, opponent);}},SCISSORS {public Outcome compete(RoShamBo4 opponent) {return compete(PAPER, opponent);}},PAPER {public Outcome compete(RoShamBo4 opponent) {return compete(ROCK, opponent);}};Outcome compete(RoShamBo4 loser, RoShamBo4 opponent) {return ((opponent == this) ? Outcome.DRAW: ((opponent == loser) ? Outcome.WIN: Outcome.LOSE));}public static void main(String[] args) {RoShamBo.play(RoShamBo4.class, 20);}
}
使用EnumMap分发
public enum RoShamBo5 implements Competitor {// 使用EnumMap分发PAPER, SCISSORS, ROCK;static EnumMap>table = new EnumMap>(RoShamBo5.class);static {for(RoShamBo5 it : RoShamBo5.values())table.put(it, new EnumMap(RoShamBo5.class));initRow(PAPER, DRAW, LOSE, WIN);initRow(SCISSORS, WIN, DRAW, LOSE);initRow(ROCK, LOSE, WIN, DRAW);}static void initRow(RoShamBo5 it,Outcome vPAPER, Outcome vSCISSORS, Outcome vROCK) {EnumMap row =RoShamBo5.table.get(it);row.put(RoShamBo5.PAPER, vPAPER);row.put(RoShamBo5.SCISSORS, vSCISSORS);row.put(RoShamBo5.ROCK, vROCK);}public Outcome compete(RoShamBo5 it) {return table.get(this).get(it);}public static void main(String[] args) {RoShamBo.play(RoShamBo5.class, 20);}
}
使用二维数组
public enum RoShamBo6 implements Competitor {// 用数组实现分发PAPER, SCISSORS, ROCK;private static Outcome[][] table = {{ DRAW, LOSE, WIN }, // PAPER{ WIN, DRAW, LOSE }, // SCISSORS{ LOSE, WIN, DRAW }, // ROCK};public Outcome compete(RoShamBo6 other) {return table[this.ordinal()][other.ordinal()];}public static void main(String[] args) {RoShamBo.play(RoShamBo6.class, 20);}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
