├── LICENSE ├── README.md ├── pom.xml └── src ├── main ├── java │ ├── algorithm │ │ ├── BigNumAdd.java │ │ ├── FindDuplicateNum.java │ │ ├── KthSmallest.java │ │ ├── Palindrome_Number_Normal.java │ │ ├── ReverseNumber.java │ │ ├── bitmap │ │ │ └── BitSetDemo1.java │ │ ├── cache_algorithm │ │ │ ├── LFUCache.java │ │ │ └── LruCache.java │ │ ├── number_to_Chinese │ │ │ ├── NumberToChinese.java │ │ │ └── NumberToChinese2.java │ │ ├── rate_limt │ │ │ └── RateLimiterGuava.java │ │ ├── recursion │ │ │ ├── BinaryConversion.java │ │ │ ├── FactorialRecursion.java │ │ │ ├── FibonacciRecursion.java │ │ │ └── RecursionDemo.java │ │ ├── reservoir_sample │ │ │ └── ReservoirSample.java │ │ ├── sort_algorithm │ │ │ ├── BinarySearch.java │ │ │ ├── BubbleSort.java │ │ │ ├── HeapSort.java │ │ │ ├── QucikSort.java │ │ │ ├── RandomUniqueNum.java │ │ │ ├── TimeComplexDemo.java │ │ │ ├── bucket_sort │ │ │ │ └── SimpleBucketSort.java │ │ │ ├── count_sort │ │ │ │ ├── BetterCountSort.java │ │ │ │ ├── ProveStableCountingSort.java │ │ │ │ ├── SimpleCountingSort.java │ │ │ │ └── Student.java │ │ │ ├── inser_sort │ │ │ │ └── InsertSort.java │ │ │ ├── merge_sort │ │ │ │ └── SimleMergeSort.java │ │ │ ├── radix_sort │ │ │ │ ├── BetterRadixSort.java │ │ │ │ └── SimpleRadixSort.java │ │ │ ├── selec_sort │ │ │ │ └── SelectSort.java │ │ │ └── shell_sort │ │ │ │ └── ShellSort.java │ │ └── string_to_int │ │ │ └── StringToInt.java │ ├── basic │ │ ├── ReturnTest.java │ │ ├── StringConcatPermanceTest.java │ │ ├── Test.java │ │ ├── assert_test │ │ │ └── DemoAssert.java │ │ ├── compare │ │ │ ├── Person.java │ │ │ └── TestCompare.java │ │ ├── reference │ │ │ ├── MyRunnable.java │ │ │ ├── MyShareObject.java │ │ │ ├── StackCallDemo.java │ │ │ ├── TestRef.java │ │ │ └── ThreadShare.java │ │ └── regex │ │ │ ├── RegTest2.java │ │ │ └── RexTest.java │ ├── class_loader │ │ ├── ClassLoaderTest.java │ │ ├── DiskClassLoader.java │ │ ├── DiskLoaderTest.java │ │ ├── Foo.java │ │ ├── StaticTest.java │ │ ├── Test.java │ │ ├── TestInitOrder.java │ │ ├── ThreadContextTest.java │ │ ├── exception │ │ │ ├── A.java │ │ │ ├── ExceptionTest.java │ │ │ ├── Loading.java │ │ │ └── NoClassFoundErrorTest.java │ │ └── passive_load │ │ │ ├── ConcurrentInitialClassTest.java │ │ │ ├── ConstantExample.java │ │ │ ├── LoadTest.java │ │ │ ├── SubClass.java │ │ │ └── SuperClass.java │ ├── concurrent │ │ ├── aqs │ │ │ ├── BooleanLatch.java │ │ │ ├── Mutex2.java │ │ │ └── MyMutex.java │ │ ├── async │ │ │ ├── AsyncTaskDemo.java │ │ │ ├── AsyncTaskDemo2.java │ │ │ └── AsyncTaskTest.java │ │ ├── atomic │ │ │ ├── AtomReferenceDemo2.java │ │ │ ├── AtomicReferenceDemo3.java │ │ │ ├── AtomicReferenceExmple.java │ │ │ └── Person.java │ │ ├── basic │ │ │ ├── DeadLockExample.java │ │ │ ├── OddEvenPrintExample.java │ │ │ ├── ProducerConsumerDemo1.java │ │ │ ├── ReorderingProblem.java │ │ │ ├── SynchronizedExample.java │ │ │ ├── ThreadDaemonExample.java │ │ │ ├── ThreadGroupDemo.java │ │ │ ├── ThreadInterruptExample.java │ │ │ ├── ThreadJoinExample.java │ │ │ ├── ThreadJoinExample2.java │ │ │ ├── ThreadLifeCycleExample.java │ │ │ ├── ThreadStarvationExample.java │ │ │ ├── ThreadStopDemp.java │ │ │ ├── ThreadYieldExample.java │ │ │ ├── VariableVisbilityProblem.java │ │ │ ├── VariableVisilityProblem2.java │ │ │ ├── VolatileNoAtomicProblem.java │ │ │ ├── WaitNotifyExample.java │ │ │ └── WaitNotifyExample2.java │ │ ├── cas │ │ │ └── CasExample.java │ │ ├── common_case │ │ │ ├── SwapPrintNumExample.java │ │ │ ├── ThreeThreadPrintByLock.java │ │ │ └── ThreeThreadPrintBySync.java │ │ ├── live_lock_demo │ │ │ ├── CommonResource.java │ │ │ ├── FinalExample.java │ │ │ ├── LiveLockExample.java │ │ │ └── Worker.java │ │ ├── lock │ │ │ ├── LockConditionExample.java │ │ │ ├── LockExample.java │ │ │ ├── LockOddEvenPrintExample.java │ │ │ ├── LockQueueExample.java │ │ │ ├── LockQueueExample2.java │ │ │ ├── LockSupportDemo.java │ │ │ ├── LockSupportExamle2.java │ │ │ ├── LockSupportFIFOMutexExample.java │ │ │ ├── SellerTicket.java │ │ │ ├── ShareCounter.java │ │ │ ├── StampLockExample1.java │ │ │ ├── StampLockPointExample2.java │ │ │ └── rwlock │ │ │ │ ├── RWLockDemo1.java │ │ │ │ ├── ReadWriteDeadLockExample.java │ │ │ │ ├── ReadWriteLockChangeStatus.java │ │ │ │ └── ReadWriteLockExample.java │ │ ├── reorder │ │ │ ├── ReorderDemo1.java │ │ │ └── ReorderDemo2.java │ │ ├── spinlock │ │ │ ├── CLHLock.java │ │ │ ├── MCSLock.java │ │ │ ├── SpinLock.java │ │ │ └── TicketLock.java │ │ ├── thread_unsafe_example │ │ │ └── ListAddAllTest.java │ │ ├── threadlocal │ │ │ ├── ThreadLocalExample1.java │ │ │ └── ThreadLocalExample2.java │ │ ├── threadpool │ │ │ ├── CompeletionServiceTest.java │ │ │ ├── ForkJoinPoolMaxTest.java │ │ │ ├── ForkJoinPoolSumTest.java │ │ │ ├── ScheduleExecutorServiceTest.java │ │ │ ├── ThreadPoolExecutorInfoTest.java │ │ │ ├── ThreadPoolExecutorTest.java │ │ │ └── ThreadPoolShutDownTest.java │ │ └── tools │ │ │ ├── blockqueue │ │ │ ├── ArrayBlockQueueDemo1.java │ │ │ ├── BlockQueuePerformanceTest.java │ │ │ ├── DelayQueueDemo1.java │ │ │ └── SynchronousQueueDemo1.java │ │ │ ├── concurrent_modify │ │ │ ├── ConcurrentModifyTest.java │ │ │ └── CopyOnWriteArraySetTest.java │ │ │ ├── concurrent_queue │ │ │ └── ConcurrentQueueTest.java │ │ │ ├── countdownlatch │ │ │ ├── CountDownDemo2.java │ │ │ ├── CountDownLatchDemo1.java │ │ │ └── CountDownLatchDemo3.java │ │ │ ├── cyclicbarrier │ │ │ ├── CyclicBarrierDemo1.java │ │ │ ├── CyclicBarrierDemo2.java │ │ │ ├── CyclicBarrierDemo3.java │ │ │ ├── CyclicBarrierDemo4.java │ │ │ └── CyclicBarrierDemo5.java │ │ │ ├── exchager │ │ │ ├── ExchangeDemo1.java │ │ │ └── ExchangeDemo2.java │ │ │ ├── map │ │ │ ├── ConcurrentHashMapTest.java │ │ │ ├── HashMapTest.java │ │ │ ├── LinkedHashMapTest.java │ │ │ └── TreeMapTest.java │ │ │ ├── phaser │ │ │ ├── PhaserDemo1.java │ │ │ ├── PhaserDemo2.java │ │ │ ├── PhaserDemo5.java │ │ │ ├── PhaserDemo6.java │ │ │ ├── PhraseDemo3.java │ │ │ └── PhraseDemo4.java │ │ │ └── semaphore │ │ │ ├── SemaphoreDemo1.java │ │ │ └── SemaphoreDemo2.java │ ├── data_structure │ │ ├── b_tree │ │ │ └── Btree.java │ │ ├── binary_tree │ │ │ ├── AVLTree.java │ │ │ ├── BST.java │ │ │ ├── L-6_2-3_Trees.pdf │ │ │ ├── MaxHeap.java │ │ │ ├── MinHeap.java │ │ │ ├── RBTree.java │ │ │ ├── SimpleTree.java │ │ │ └── Tree23.java │ │ ├── linked_list │ │ │ ├── DoubleLinkedList.java │ │ │ ├── SinglyLinkedList.java │ │ │ └── SinglyLinkedList2.java │ │ ├── skip_list │ │ │ ├── SkipList.java │ │ │ └── SkipListUseArray.java │ │ └── tree_search │ │ │ └── BinarySearch.java │ ├── design_pattern │ │ ├── callback │ │ │ ├── demo1 │ │ │ │ ├── CallBack.java │ │ │ │ ├── CallBackImpl.java │ │ │ │ └── Caller.java │ │ │ └── demo2 │ │ │ │ ├── AppMain.java │ │ │ │ ├── CallBack.java │ │ │ │ ├── Student.java │ │ │ │ └── Teacher.java │ │ └── singleton │ │ │ ├── create │ │ │ ├── DoubleCheckSingleton.java │ │ │ ├── EnumSingleton.java │ │ │ ├── SimpleSingleton.java │ │ │ └── StaicNestedSingleton.java │ │ │ └── destroy_singly │ │ │ ├── MyClassLoader.java │ │ │ ├── Singleton.java │ │ │ └── TestDestroySingleton.java │ ├── gc │ │ └── Demo.java │ ├── io │ │ ├── file_io │ │ │ └── asyn_io │ │ │ │ └── AsynIODemo.java │ │ ├── io_model │ │ │ ├── v1_bio │ │ │ │ ├── V1Handler.java │ │ │ │ ├── V1TimeClient.java │ │ │ │ └── V1TimeServer.java │ │ │ ├── v2_nio │ │ │ │ ├── MultiplexClient.java │ │ │ │ └── MultiplexServer.java │ │ │ └── v3_aio │ │ │ │ ├── AioClient.java │ │ │ │ ├── AioServer.java │ │ │ │ └── CustomAttachment.java │ │ └── io_test │ │ │ ├── NioReadWrite.java │ │ │ └── NioSelectTest.java │ ├── leetcode │ │ ├── easy │ │ │ ├── array_all │ │ │ │ ├── AddToArrayForm.java │ │ │ │ ├── ArrayPairSum.java │ │ │ │ ├── BestTimeSellStock.java │ │ │ │ ├── BestTimeSellStockII.java │ │ │ │ ├── CanPlaceFlowers.java │ │ │ │ ├── ContainsDuplicate.java │ │ │ │ ├── ContainsDuplicateII.java │ │ │ │ ├── DegreeArray.java │ │ │ │ ├── FibonacciNumber.java │ │ │ │ ├── FindCommonsCharacters.java │ │ │ │ ├── FindDiappearedInArray.java │ │ │ │ ├── FindPivotIndex.java │ │ │ │ ├── FlippingArrayImg.java │ │ │ │ ├── HeightChecker.java │ │ │ │ ├── KdiffPairs.java │ │ │ │ ├── KindDeckCards.java │ │ │ │ ├── LargeGroups.java │ │ │ │ ├── LargestNumberTwice.java │ │ │ │ ├── LongestContinuousSubsequence.java │ │ │ │ ├── MajorityElement.java │ │ │ │ ├── MatrixDiagonal.java │ │ │ │ ├── MaxConsecutiveOnes.java │ │ │ │ ├── MaximizeDistance.java │ │ │ │ ├── MaximumAverageSubarray.java │ │ │ │ ├── MaximumProductThreeNumbers.java │ │ │ │ ├── MaxinumSubArray.java │ │ │ │ ├── MergeSortedArray1.java │ │ │ │ ├── MinCostClimbingStairs.java │ │ │ │ ├── MissingNumber.java │ │ │ │ ├── MonotonicArray.java │ │ │ │ ├── MoveZeroes.java │ │ │ │ ├── NonDecreasingArray.java │ │ │ │ ├── OneTwoBits.java │ │ │ │ ├── PairsofSongs.java │ │ │ │ ├── PartitionArrayEqualSum.java │ │ │ │ ├── PascalTriangle.java │ │ │ │ ├── PlusOne.java │ │ │ │ ├── RemoveDuplicateSortedArray.java │ │ │ │ ├── RemoveElement.java │ │ │ │ ├── ReplaceGreatestElementRightSide.java │ │ │ │ ├── ReshapeMartix.java │ │ │ │ ├── RotateArray.java │ │ │ │ ├── SearchInsertPosition.java │ │ │ │ ├── SelfDividingNumbers.java │ │ │ │ ├── ShortestUnsortedArray.java │ │ │ │ ├── SortArrayByParity.java │ │ │ │ ├── SortArrayByParity2.java │ │ │ │ ├── SortSpecialRange.java │ │ │ │ ├── SortedArraySquare.java │ │ │ │ ├── SumEvenNumber.java │ │ │ │ ├── ThirdMaximumNumber.java │ │ │ │ ├── TransposeMatrix.java │ │ │ │ ├── TwoSum2.java │ │ │ │ ├── TwoSum_Better.java │ │ │ │ └── ValidMountainArray.java │ │ │ ├── hash_table_all │ │ │ │ ├── BullsAndCows.java │ │ │ │ ├── CountPrimes.java │ │ │ │ ├── DailyTemperatures.java │ │ │ │ ├── DistributeCandies.java │ │ │ │ ├── EmployeeImportance.java │ │ │ │ ├── FindDifference.java │ │ │ │ ├── FindGoodWords.java │ │ │ │ ├── HappyNumber.java │ │ │ │ ├── InterSectionTwoArray.java │ │ │ │ ├── IntersectionTwoArraysII.java │ │ │ │ ├── IslandPerimeter.java │ │ │ │ ├── IsomorphicStrings.java │ │ │ │ ├── JewelsandStones.java │ │ │ │ ├── KeyboardRow.java │ │ │ │ ├── LongestHarmoniousSubsequence.java │ │ │ │ ├── LongestPalindrome.java │ │ │ │ ├── LongestWordinDictionary.java │ │ │ │ ├── MinimumIndexSumofTwoLists.java │ │ │ │ ├── MyHashMap.java │ │ │ │ ├── MyHashMap2.java │ │ │ │ ├── MyHashSet.java │ │ │ │ ├── NumberofBoomerangs.java │ │ │ │ ├── OccurrencesAfterBigram.java │ │ │ │ ├── PowerfulInteger.java │ │ │ │ ├── SetMismatch.java │ │ │ │ ├── ShortestCompletingWord.java │ │ │ │ ├── SingleNumber.java │ │ │ │ ├── Size2NElement.java │ │ │ │ ├── SubdomainVisitCount.java │ │ │ │ ├── UncommonWordTwoSentences.java │ │ │ │ ├── ValidAnagram.java │ │ │ │ ├── VerifyingAlienDictionary.java │ │ │ │ └── WordPattern.java │ │ │ ├── linklist_all │ │ │ │ ├── AddTwoNumbers.java │ │ │ │ ├── FindFirstCrossNode.java │ │ │ │ ├── LinkListCheckCircle.java │ │ │ │ ├── ListNode.java │ │ │ │ ├── MiddleLinkList.java │ │ │ │ ├── MyLinkList.java │ │ │ │ └── RemoveDuplicate.java │ │ │ ├── math │ │ │ │ ├── BinaryGap.java │ │ │ │ ├── ComplementBaseInteger.java │ │ │ │ ├── DIStringMatch.java │ │ │ │ ├── DistributeCandiesToPeople.java │ │ │ │ ├── DivisorGame.java │ │ │ │ ├── LargestPerimeterTriangle.java │ │ │ │ ├── LargestTriangleArea.java │ │ │ │ ├── ProjectionArea3DShapes.java │ │ │ │ └── SmallestRange.java │ │ │ ├── string_all │ │ │ │ ├── BuddyString.java │ │ │ │ ├── CheckPalindrome2.java │ │ │ │ ├── CountAndSay.java │ │ │ │ ├── FirstUniqueCharacter.java │ │ │ │ ├── ImplementStr.java │ │ │ │ ├── LastWordLength.java │ │ │ │ ├── LongPressedName.java │ │ │ │ ├── LongestCommonPrefix.java │ │ │ │ ├── MostCommonWord.java │ │ │ │ ├── NumUniqueEmails.java │ │ │ │ ├── NumberSegmentsString.java │ │ │ │ ├── RansomNote.java │ │ │ │ ├── RepeatedStringMatch.java │ │ │ │ ├── RepeatedSubstring.java │ │ │ │ ├── ReverseString2.java │ │ │ │ ├── ReverseVowelsString.java │ │ │ │ ├── StringCompression.java │ │ │ │ ├── StudentAttendanceRecoder.java │ │ │ │ ├── VaildParenttheses.java │ │ │ │ ├── ValidPalindrome3.java │ │ │ │ ├── construct_string_from_tree │ │ │ │ │ └── ConstructStringBinaryTree.java │ │ │ │ ├── count_binaray_substring │ │ │ │ │ └── CountBinarySubstring.java │ │ │ │ ├── detect_capital │ │ │ │ │ └── DetectCapital.java │ │ │ │ ├── goat_latin │ │ │ │ │ └── GoatLatin.java │ │ │ │ ├── group_special_equivalent │ │ │ │ │ └── GroupSpecialEquivalent.java │ │ │ │ ├── morse_unqiue_code │ │ │ │ │ └── UniqueMorseCode.java │ │ │ │ ├── recoder_log_file │ │ │ │ │ └── RecoderLogFile.java │ │ │ │ ├── reverse_only_letters │ │ │ │ │ └── ReverseOnlyLetters.java │ │ │ │ ├── reverse_word │ │ │ │ │ ├── ReverseWord1.java │ │ │ │ │ └── ReverseWord2.java │ │ │ │ ├── robot_return_origin │ │ │ │ │ └── RobotReturnOrigin.java │ │ │ │ ├── roman_to_integer │ │ │ │ │ └── RomanToInteger.java │ │ │ │ ├── rotated_digits │ │ │ │ │ └── RotatedDigits.java │ │ │ │ └── string_to_lower_case │ │ │ │ │ └── Solution.java │ │ │ └── tree_all │ │ │ │ ├── AverageLevelTree.java │ │ │ │ ├── BSTreeToGreater.java │ │ │ │ ├── BinaryBottomUpTreeLevel.java │ │ │ │ ├── BinaryTreePath.java │ │ │ │ ├── BinaryTreeTilt.java │ │ │ │ ├── CheckBalancedBinaryTree.java │ │ │ │ ├── CousinsBinaryTree.java │ │ │ │ ├── DiameterBinaryTree.java │ │ │ │ ├── FindModeBST.java │ │ │ │ ├── IncreasingOrderSearchTree.java │ │ │ │ ├── InvertBinaryTree.java │ │ │ │ ├── LeafSimilar.java │ │ │ │ ├── LevelOrderTraversal.java │ │ │ │ ├── LongestUniValuePath.java │ │ │ │ ├── LowestCommonAncestor.java │ │ │ │ ├── MergeTree.java │ │ │ │ ├── MinimumAbsoluteDifference.java │ │ │ │ ├── MinimumDepth.java │ │ │ │ ├── NTreeTraveser.java │ │ │ │ ├── Node.java │ │ │ │ ├── PathInLabledBinaryTree.java │ │ │ │ ├── PathSum1.java │ │ │ │ ├── PathSumIII.java │ │ │ │ ├── RangeSumBST.java │ │ │ │ ├── SameTree.java │ │ │ │ ├── SecondMinimumNode.java │ │ │ │ ├── SortedArrayToSearchTree.java │ │ │ │ ├── SubtreeAnotherTree.java │ │ │ │ ├── SumLeftLeaves.java │ │ │ │ ├── SumRootToLeaf.java │ │ │ │ ├── SymmetricTree.java │ │ │ │ ├── TreeNode.java │ │ │ │ ├── TrieByArray.java │ │ │ │ ├── TrieByMap.java │ │ │ │ ├── TrimBST.java │ │ │ │ ├── TwoSumInBinaryTree.java │ │ │ │ └── UnivaluedBinaryTree.java │ │ └── medium │ │ │ ├── array │ │ │ └── RevealCardsIncreasingOrder.java │ │ │ ├── math │ │ │ └── TinyURL.java │ │ │ └── string │ │ │ └── FindReplacePattern.java │ ├── memory_gc │ │ ├── DemoTest.java │ │ └── MemoryTest.java │ ├── netty │ │ ├── discard_server │ │ │ ├── DiscardServer.java │ │ │ └── DiscardServerHandler.java │ │ └── time_server │ │ │ ├── TimeClient.java │ │ │ ├── TimeClientHandler.java │ │ │ └── TimeServerHandler.java │ ├── proxy │ │ ├── cglib_dynamic_proxy │ │ │ ├── Hello.java │ │ │ ├── MyInterceptor.java │ │ │ └── TestMain.java │ │ ├── jdk_dynamic_proxy │ │ │ ├── CountTimeProxyInvocation.java │ │ │ ├── SaveClassToDisk.java │ │ │ ├── SimpleInvocation.java │ │ │ ├── TestCountTimeProxy.java │ │ │ └── TestSimpleProxy.java │ │ └── static_proxy │ │ │ ├── Animal.java │ │ │ ├── Cat.java │ │ │ ├── Dog.java │ │ │ ├── ProxyRole.java │ │ │ └── TestMain.java │ └── reflection │ │ ├── Person.java │ │ ├── ReflectionDemo1.java │ │ ├── ReflectionTest.java │ │ ├── base │ │ ├── BaseClass.java │ │ ├── BaseImpl.java │ │ ├── BaseInterface.java │ │ └── TestReflection.java │ │ └── generics_type │ │ └── MyClass.java └── resources │ ├── class │ ├── Demo.class │ ├── Demo.java │ └── Singleton.class │ └── pic │ ├── Java并发知识全景.png │ ├── jvm运行区域.jpg │ ├── sub-thread.jpg │ ├── threadpool_v2.jpg │ └── 数据类型.png └── test └── java └── TestStr.java /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 qindongliang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/algorithm/Palindrome_Number_Normal.java: -------------------------------------------------------------------------------- 1 | package algorithm; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/15. 5 | * 判断是否为回文数字 6 | */ 7 | public class Palindrome_Number_Normal { 8 | 9 | 10 | public static boolean isPalindrome(int x) { 11 | 12 | //边界校验 13 | if(x<0) return false; 14 | //赋一个临时值 15 | int temp=x; 16 | //用来存储反转后的数字 17 | long reverse=0; 18 | while(temp>0){ 19 | //对原数每次缩小10倍后取模,依次从右到左得到每个数字 20 | //循环的次数就是放大的倍数,每次乘以10加上余数就能够得到反转的数字 21 | reverse=reverse*10+temp%10; 22 | temp=temp/10; 23 | 24 | } 25 | //判断临街值 26 | if(reverse>Integer.MAX_VALUE) return false; 27 | 28 | 29 | return reverse==x; 30 | } 31 | 32 | 33 | public static void main(String[] args) { 34 | 35 | 36 | boolean flag= isPalindrome(12621); 37 | 38 | 39 | System.out.println(flag); 40 | 41 | 42 | 43 | 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/algorithm/ReverseNumber.java: -------------------------------------------------------------------------------- 1 | package algorithm; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/10. 5 | */ 6 | public class ReverseNumber { 7 | 8 | 9 | public static int reverse(int x) { 10 | 11 | int temp=x; 12 | 13 | if (x<0){ 14 | temp=x* -1; 15 | } 16 | 17 | long reverse=0; 18 | 19 | while (temp>0){ 20 | reverse=reverse*10+ temp%10; 21 | temp=temp/10; 22 | } 23 | 24 | if(reverse>Integer.MAX_VALUE) return 0; 25 | 26 | if(x<0) return (int)reverse* -1; 27 | 28 | 29 | return (int)reverse; 30 | 31 | } 32 | 33 | public static void main(String[] args) { 34 | 35 | 36 | System.out.println(reverse(-1563847412)); 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/algorithm/rate_limt/RateLimiterGuava.java: -------------------------------------------------------------------------------- 1 | package algorithm.rate_limt; 2 | 3 | import com.google.common.util.concurrent.RateLimiter; 4 | 5 | /*** 6 | * 7 | * 令牌桶算法示例 8 | * 9 | */ 10 | public class RateLimiterGuava { 11 | 12 | public static void main(String[] args) { 13 | 14 | //创建一个桶容量为5,并且每秒增加5个令牌,也就是每200ms放入一个令牌 15 | RateLimiter limiter=RateLimiter.create(5); 16 | 17 | System.out.println(limiter.acquire()); 18 | System.out.println(limiter.acquire()); 19 | System.out.println(limiter.acquire()); 20 | System.out.println(limiter.acquire()); 21 | System.out.println(limiter.acquire()); 22 | 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/algorithm/recursion/BinaryConversion.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | /** 4 | * 十进制转换大于2进制的任意进制 5 | * Created by qindongliang on 2018/10/13. 6 | */ 7 | public class BinaryConversion { 8 | 9 | static char item[]="0123456789ABCDEF".toCharArray(); 10 | 11 | /*** 12 | * 13 | * @param sb 输出结果 14 | * @param n 要转换的10进制数字 15 | * @param digit 要转的进制 16 | * @return 17 | */ 18 | private static StringBuilder conversion(StringBuilder sb,int n,int digit){ 19 | 20 | if(digit<2){ 21 | digit=2; 22 | } 23 | 24 | if(n<=0){ 25 | return sb.append(""); 26 | } 27 | StringBuilder reuslt=conversion(sb,n/digit,digit); 28 | return reuslt.append(item[n%digit]); 29 | 30 | } 31 | 32 | 33 | public static void main(String[] args) { 34 | 35 | System.out.println(conversion(new StringBuilder(),10,2)); 36 | 37 | } 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/algorithm/recursion/FactorialRecursion.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | /** 4 | * 5 | * 使用递归算法实现阶乘的例子 6 | * 7 | * Created by qindongliang on 2018/10/13. 8 | */ 9 | public class FactorialRecursion { 10 | 11 | 12 | public static int factrial(int n){ 13 | if(n<1){ 14 | return 1; 15 | } 16 | return n*factrial(n-1); 17 | 18 | } 19 | 20 | public static int factrialDetail(int n){ 21 | if(n<1){ 22 | System.out.println("拆解问题完毕,开始分而治之"); 23 | return 1; 24 | } 25 | System.out.println("f("+n+")="+n+" * f("+(n-1)+")"); 26 | int z= n*factrialDetail(n-1); 27 | 28 | System.out.println("f("+n+")="+z); 29 | 30 | return z; 31 | 32 | } 33 | 34 | 35 | 36 | 37 | 38 | public static void main(String[] args) { 39 | 40 | factrialDetail(5); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/algorithm/recursion/FibonacciRecursion.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | /** 4 | * 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 5 | * 斐波那契数列(意大利语:Successione di Fibonacci),黄金分割数列。 6 | * 7 | * Created by qindongliang on 2018/10/13. 8 | */ 9 | public class FibonacciRecursion { 10 | 11 | 12 | public static int fibonacci(int n){ 13 | if(n<0){ 14 | throw new IllegalArgumentException("传入参数不合法"); 15 | } 16 | if(n<=2) { 17 | return 1; 18 | }; 19 | //先计算第一个递归函数 20 | int plusItem1=fibonacci(n-1); 21 | int plusItem2=fibonacci(n-2); 22 | int sum=plusItem1+plusItem2; 23 | 24 | return sum; 25 | 26 | } 27 | 28 | public static void main(String[] args) { 29 | 30 | System.out.println(fibonacci(4)); 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/algorithm/recursion/RecursionDemo.java: -------------------------------------------------------------------------------- 1 | package algorithm.recursion; 2 | 3 | /** 4 | * Created by qindongliang on 2018/10/13. 5 | */ 6 | public class RecursionDemo { 7 | 8 | static int count1=0; 9 | static int count2=0; 10 | 11 | 12 | public static void test1(){ 13 | if(count1==5){ 14 | System.out.println("=============递归1拆解完毕,开始分治=================="); 15 | return; 16 | } 17 | count1++; 18 | System.out.println("递归方法1调用,当前栈深度: "+count1); 19 | test1(); 20 | System.out.println("递归方法1返回,当前栈深度: "+count1--); 21 | } 22 | 23 | 24 | public static void test2(){ 25 | 26 | if(count2==5){ 27 | System.out.println("=============递归2拆解完毕,开始分治=================="); 28 | return; 29 | } 30 | count2++; 31 | System.out.println("递归方法2调用,当前栈深度: "+count2); 32 | test2(); 33 | System.out.println("***********递归方法2返回,当前栈深度: "+count2--+"**************"); 34 | test1(); 35 | // System.out.println("递归返回,当前栈深度: "+count2--); 36 | } 37 | 38 | 39 | 40 | public static void main(String[] args) { 41 | 42 | 43 | // test1(); 44 | 45 | test2(); 46 | 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm; 2 | 3 | import java.util.Arrays; 4 | 5 | public class BinarySearch { 6 | 7 | public static void main(String[] args) { 8 | 9 | //必须要求数组是排好序的,否则就结果就有问题 10 | int a[]={66,3,77,6,8,}; 11 | 12 | Arrays.sort(a); 13 | System.out.println(Arrays.toString(a)); 14 | 15 | int searchKey=27; 16 | int start=0; 17 | int end=a.length-1; 18 | 19 | while (start<=end){ 20 | 21 | // int mid=(start+end)/2; 22 | int mid=(start+end)>>>1; 23 | 24 | int midVal=a[mid]; 25 | 26 | if(midValsearchKey){ 29 | end=mid-1; 30 | }else{ 31 | System.out.println(" 找到数据,数组下标:"+mid); 32 | return; 33 | } 34 | 35 | 36 | } 37 | System.out.println("没有找到数据.."); 38 | 39 | 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/RandomUniqueNum.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class RandomUniqueNum { 7 | 8 | private static int range=10; 9 | private static int[] result; 10 | 11 | public static void main(String[] args) { 12 | 13 | int a1[]=new int[range]; 14 | int a2[]=new int[range]; 15 | 16 | for (int i = 0; i < range; i++) { 17 | a1[i]=i;//初始化放入N个不重复的数 18 | } 19 | 20 | Random random=new Random(); 21 | int end=range-1; 22 | 23 | for (int j = 0; j <10 ; j++) { 24 | 25 | int num=random.nextInt(end+1); //随机数的范围是1-100 26 | a2[j]=a1[num];//从数组1里面取出来随机数,放在数组2里面 27 | a1[num]=a1[end];//把取过的数,放在最后一位 28 | end--; 29 | 30 | } 31 | 32 | System.out.println(Arrays.toString(a2)); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/TimeComplexDemo.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/8. 5 | */ 6 | public class TimeComplexDemo { 7 | 8 | public void constantTime(int a,int b){ 9 | int sum=a+b; 10 | System.out.println(sum); 11 | } 12 | 13 | 14 | public static void main(String[] args) { 15 | 16 | 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/count_sort/Student.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm.count_sort; 2 | 3 | public class Student { 4 | 5 | private int grade; 6 | private String name; 7 | 8 | public Student() { 9 | } 10 | 11 | public Student(int grade, String name) { 12 | this.grade = grade; 13 | this.name = name; 14 | } 15 | 16 | public int getGrade() { 17 | return grade; 18 | } 19 | 20 | public void setGrade(int grade) { 21 | this.grade = grade; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "Student{" + 35 | "grade=" + grade + 36 | ", name='" + name + '\'' + 37 | '}'; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/inser_sort/InsertSort.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm.inser_sort; 2 | 3 | import java.util.Arrays; 4 | 5 | /**** 6 | * 算法思想: 7 | * 遍历数组中每一个元素,每一个元素都会和前面所有的已经有序的集合元素 8 | * 进行比较,从而确定每一个元素的位置,这里故意拿一个 9 | * 降序好的例子,来做升序排序,比较典型的反映这种算法的思想。 10 | * 平均时间复杂度:О(n²) 11 | * 平均空间复杂度:O(1) 12 | * 是否稳定:是稳定排序算法 13 | * 14 | */ 15 | 16 | public class InsertSort { 17 | 18 | public static void sort(int[] numbers){ 19 | for (int i = 1; i < numbers.length; i++) { 20 | //取遍历的每一个元素 21 | int currentNumber = numbers[i]; 22 | int j = i - 1; 23 | //每一个元素,都会与前面所有的有序元素集合进行比较 24 | //从而交换自己的位置 25 | while (j >= 0 && numbers[j] > currentNumber) { 26 | numbers[j + 1] = numbers[j]; 27 | j--; 28 | } 29 | //找到当前元素的位置,然后交换。 30 | numbers[j + 1] = currentNumber; 31 | System.out.println(Arrays.toString(numbers)); 32 | } 33 | } 34 | 35 | public static void main(String[] args) { 36 | 37 | int a[]={10,9,8,7,6}; 38 | 39 | sort(a);//排序 40 | 41 | 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/algorithm/sort_algorithm/selec_sort/SelectSort.java: -------------------------------------------------------------------------------- 1 | package algorithm.sort_algorithm.selec_sort; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * 算法思想: 7 | * 选择排序算法假设无序的数组是有序的,那么 8 | * 数组每个位置上的元素一定是,从当前位置开始到结尾中 9 | * 最小的,基于这个假设,选择排序每次都会查找从其位置 10 | * 开始到末尾中的最小元素的下标,找到之后,交换当前位置的值 11 | * 与最小值,反复如此就能把无序数组,给排序好 12 | * 13 | * 平均时间复杂度:О(n²) 14 | * 平均空间复杂度:O(1) 15 | * 是否稳定:不是稳定排序算法 16 | * 17 | */ 18 | public class SelectSort { 19 | 20 | public static void sort(int arr[]){ 21 | 22 | int min;//存储每次遍历得到的最小元素的数组下标值 23 | int swap;//存储代待交换元素的值 24 | for (int i = 0; i < arr.length; i++) { 25 | //依次数组的下标赋值 26 | min = i; 27 | //遍历剩余部分的元素,找到最小值的下标 28 | for (int j = i; j < arr.length; j++) { 29 | // 比较元素值 30 | if (arr[j] < arr[min]) { 31 | min = j;//下标赋值 32 | } 33 | } 34 | //每次把最小值提前 35 | swap = arr[min]; 36 | arr[min] = arr[i]; 37 | arr[i] = swap; 38 | 39 | System.out.println(Arrays.toString(arr)); 40 | } 41 | 42 | } 43 | 44 | 45 | public static void main(String[] args) { 46 | 47 | int a[]={10,19,8,7,1}; 48 | sort(a); 49 | 50 | 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/algorithm/string_to_int/StringToInt.java: -------------------------------------------------------------------------------- 1 | package algorithm.string_to_int; 2 | 3 | /*** 4 | * Convert string to integer number. 5 | */ 6 | public class StringToInt { 7 | 8 | private static int stringToInt(String s){ 9 | // Having one number at least. 10 | if(!s.matches("\\d+")){ 11 | return -1; 12 | } 13 | 14 | char []array=s.toCharArray(); 15 | 16 | int lastIndex=array.length-1; 17 | int radix=0; 18 | int result=0; 19 | 20 | // right to left compute 21 | while (lastIndex>=0){ 22 | int asciiToNumber= array[lastIndex] - 48; 23 | result += Math.pow(10,radix) * asciiToNumber ; 24 | radix++; 25 | lastIndex--; 26 | } 27 | 28 | return result; 29 | 30 | 31 | } 32 | 33 | 34 | public static void main(String[] args) { 35 | 36 | System.out.println(stringToInt("1113")); 37 | 38 | 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/basic/Test.java: -------------------------------------------------------------------------------- 1 | package basic; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/23. 5 | */ 6 | public class Test { 7 | 8 | public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { 9 | 10 | //默认是类初始化,可以选择关闭 11 | // Class c= Class.forName("basic.ReturnTest"); 12 | 13 | 14 | //关闭类的初始化 15 | Class c1= Class.forName("basic.ReturnTest",true,ReturnTest.class.getClassLoader()); 16 | // c1.newInstance();//实例初始化 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/basic/assert_test/DemoAssert.java: -------------------------------------------------------------------------------- 1 | package basic.assert_test; 2 | 3 | /** 4 | * Created by qindongliang on 2018/12/31. 5 | */ 6 | public class DemoAssert { 7 | 8 | 9 | public static String get(){ 10 | return "abccacd"; 11 | } 12 | 13 | 14 | public static void checkName(String name){ 15 | assert name!=null:"name is empty"; 16 | } 17 | 18 | public static void checkAge(int age){ 19 | assert age>0 && age<=18; 20 | } 21 | 22 | 23 | public static void main(String[] args) { 24 | 25 | checkName(null);//测试校验 26 | 27 | 28 | // checkAge(25)//测试范围 29 | 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/basic/compare/Person.java: -------------------------------------------------------------------------------- 1 | package basic.compare; 2 | 3 | public class Person implements Comparable { 4 | 5 | 6 | private int age; 7 | private String name; 8 | 9 | public Person(int age, String name) { 10 | this.age = age; 11 | this.name = name; 12 | } 13 | 14 | public int getAge() { 15 | return age; 16 | } 17 | 18 | public void setAge(int age) { 19 | this.age = age; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | @Override 31 | public int compareTo(Person o) { 32 | return this.age-o.age; 33 | } 34 | 35 | 36 | @Override 37 | public String toString() { 38 | return "Person{" + 39 | "age=" + age + 40 | ", name='" + name + '\'' + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/basic/reference/MyRunnable.java: -------------------------------------------------------------------------------- 1 | package basic.reference; 2 | 3 | public class MyRunnable implements Runnable { 4 | 5 | @Override 6 | public void run() { 7 | 8 | } 9 | 10 | 11 | public void one(){ 12 | int local=45; 13 | MyShareObject copy=MyShareObject.shareInstance; 14 | 15 | 16 | two(); 17 | } 18 | 19 | 20 | 21 | public void two(){ 22 | 23 | Integer localVariable1 = new Integer(99); 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/basic/reference/MyShareObject.java: -------------------------------------------------------------------------------- 1 | package basic.reference; 2 | 3 | public class MyShareObject { 4 | 5 | 6 | public static final MyShareObject shareInstance=new MyShareObject(); 7 | 8 | public Integer object2 = new Integer(22); 9 | public Integer object4 = new Integer(44); 10 | 11 | public long member1 = 12345; 12 | public long member2 = 67890; 13 | 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/basic/reference/StackCallDemo.java: -------------------------------------------------------------------------------- 1 | package basic.reference; 2 | 3 | public class StackCallDemo { 4 | 5 | 6 | static class Cat{ 7 | public String name; 8 | } 9 | 10 | public void m1(){ 11 | int x=20; 12 | m2(x);// call m2 method 13 | } 14 | 15 | 16 | public void m2(int x){ 17 | boolean c; 18 | m3();//call m3 method 19 | } 20 | 21 | 22 | public void m3(){ 23 | Cat cat=new Cat(); 24 | //more code 25 | } 26 | 27 | 28 | public static void main(String[] args) { 29 | 30 | 31 | StackCallDemo stackDemo=new StackCallDemo(); 32 | stackDemo.m1(); 33 | 34 | } 35 | 36 | 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/class_loader/DiskLoaderTest.java: -------------------------------------------------------------------------------- 1 | package class_loader; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/24. 5 | */ 6 | public class DiskLoaderTest { 7 | 8 | public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { 9 | 10 | 11 | String path="src/main/resources/class/Demo.class"; 12 | DiskClassLoader diskClassLoader=new DiskClassLoader(path); 13 | 14 | // Class c= diskClassLoader.loadClass(path); 15 | 16 | Class c = Class.forName("Demo",false,diskClassLoader); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/class_loader/StaticTest.java: -------------------------------------------------------------------------------- 1 | package class_loader; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/24. 5 | */ 6 | public class StaticTest { 7 | 8 | public static final int a=5; 9 | 10 | 11 | static { 12 | System.out.println("abc"); 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/class_loader/Test.java: -------------------------------------------------------------------------------- 1 | package class_loader; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/24. 5 | */ 6 | public class Test { 7 | 8 | 9 | public static void main(String[] args) { 10 | 11 | 12 | System.out.println(StaticTest.a); 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/class_loader/TestInitOrder.java: -------------------------------------------------------------------------------- 1 | package class_loader; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/23. 5 | */ 6 | public class TestInitOrder { 7 | 8 | public static void main(String[] args) { 9 | 10 | 11 | 12 | Too too=new Too(); 13 | 14 | 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/class_loader/exception/A.java: -------------------------------------------------------------------------------- 1 | package class_loader.exception; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/26. 5 | */ 6 | public class A { 7 | 8 | public void hello(){ 9 | 10 | System.out.println("A hello"); 11 | } 12 | 13 | } 14 | 15 | class B { 16 | 17 | public static void main(String[] args) { 18 | 19 | A a=new A();//如果A类的class文件,在运行时找不到,就会抛出NoClassDefFoundError异常。 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/class_loader/exception/ExceptionTest.java: -------------------------------------------------------------------------------- 1 | package class_loader.exception; 2 | 3 | public class ExceptionTest { 4 | 5 | public static void main(String[] args)throws Exception { 6 | 7 | 8 | Class.forName("oracle.jdbc.driver.OracleDriver"); 9 | 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/class_loader/exception/Loading.java: -------------------------------------------------------------------------------- 1 | package class_loader.exception; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/25. 5 | */ 6 | public class Loading { 7 | 8 | static double i=1/0;//故意使得类初始化失败 9 | 10 | public static void print(){ 11 | 12 | System.out.println("123"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/class_loader/exception/NoClassFoundErrorTest.java: -------------------------------------------------------------------------------- 1 | package class_loader.exception; 2 | 3 | /** 4 | * Created by qindongliang on 2018/9/25. 5 | */ 6 | public class NoClassFoundErrorTest { 7 | 8 | public static void main(String[] args) { 9 | 10 | try { 11 | double i=Loading.i; 12 | }catch (Throwable e){//此处,必须用Throwable,用Exception会直接退出。 13 | System.out.println(e); 14 | } 15 | 16 | 17 | //继续使用 18 | Loading.print(); 19 | 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/class_loader/passive_load/ConcurrentInitialClassTest.java: -------------------------------------------------------------------------------- 1 | package class_loader.passive_load; 2 | 3 | public class ConcurrentInitialClassTest { 4 | 5 | 6 | public static void main(String[] args) { 7 | 8 | 9 | 10 | Runnable runnable=new Runnable() { 11 | @Override 12 | public void run() { 13 | System.out.println(Thread.currentThread().getName()+" 开始启动..... "); 14 | new ConstantExample();//静态类会初始化 15 | 16 | } 17 | }; 18 | 19 | 20 | Thread t1=new Thread(runnable); 21 | Thread t2=new Thread(runnable); 22 | 23 | t1.start(); 24 | t2.start(); 25 | 26 | 27 | 28 | 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/class_loader/passive_load/ConstantExample.java: -------------------------------------------------------------------------------- 1 | package class_loader.passive_load; 2 | 3 | public class ConstantExample { 4 | 5 | 6 | public static final int age=18; 7 | 8 | static { 9 | 10 | if(true){ 11 | System.out.println(Thread.currentThread().getName()+" 开始初始化类"); 12 | while (true){ 13 | 14 | } 15 | 16 | } 17 | 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/class_loader/passive_load/LoadTest.java: -------------------------------------------------------------------------------- 1 | package class_loader.passive_load; 2 | 3 | public class LoadTest { 4 | public static void main(String[] args) { 5 | 6 | //例子一 仅仅触发父类初始化,不会触发子类的初始化 7 | // System.out.println(SubClass.value); 8 | 9 | 10 | // 例子二 声明数组也不会触发类的初始化 11 | //SubClass arrs[]=new SubClass[5]; 12 | 13 | 14 | // 例子三 对于常量访问也不会触发 15 | System.out.println(ConstantExample.age); 16 | 17 | 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/class_loader/passive_load/SubClass.java: -------------------------------------------------------------------------------- 1 | package class_loader.passive_load; 2 | 3 | public class SubClass extends SuperClass { 4 | 5 | static { 6 | 7 | System.out.println("子类初始化了........"); 8 | 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/class_loader/passive_load/SuperClass.java: -------------------------------------------------------------------------------- 1 | package class_loader.passive_load; 2 | 3 | public class SuperClass { 4 | 5 | 6 | static int value=5; 7 | 8 | static { 9 | 10 | System.out.println("父类初始化了......."); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/concurrent/aqs/BooleanLatch.java: -------------------------------------------------------------------------------- 1 | package concurrent.aqs; 2 | 3 | import java.util.concurrent.locks.AbstractQueuedSynchronizer; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/12. 7 | */ 8 | public class BooleanLatch { 9 | 10 | private static class Sync extends AbstractQueuedSynchronizer{ 11 | 12 | 13 | boolean isSignalled() { return getState() != 0; } 14 | 15 | protected int tryAcquireShared(int ignore) { 16 | return isSignalled() ? 1 : -1; 17 | } 18 | protected boolean tryReleaseShared(int ignore) { 19 | setState(1); 20 | return true; 21 | } 22 | 23 | 24 | } 25 | 26 | private final Sync sync = new Sync(); 27 | public boolean isSignalled() { return sync.isSignalled(); } 28 | public void signal() { sync.releaseShared(1); } 29 | public void await() throws InterruptedException { 30 | sync.acquireSharedInterruptibly(1); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/concurrent/async/AsyncTaskTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.async; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | import static junit.framework.TestCase.assertTrue; 6 | 7 | public class AsyncTaskTest { 8 | 9 | public static void main(String[] args) { 10 | 11 | // https://juejin.im/post/5adbf8226fb9a07aac240a67 12 | StringBuilder result = new StringBuilder(); 13 | CompletableFuture.completedFuture("thenAccept message") 14 | .thenAccept(s ->result.append(s)); 15 | // assertTrue("Result was empty", result.length() > 0); 16 | 17 | 18 | System.out.println(result.toString()); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/concurrent/atomic/AtomReferenceDemo2.java: -------------------------------------------------------------------------------- 1 | package concurrent.atomic; 2 | 3 | import java.util.concurrent.atomic.AtomicReference; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/5. 7 | */ 8 | public class AtomReferenceDemo2 { 9 | 10 | static class Person{ 11 | 12 | public String name; 13 | public volatile boolean flag; 14 | 15 | } 16 | 17 | public static AtomicReference atomic=new AtomicReference<>(); 18 | 19 | 20 | public static void main(String[] args) { 21 | 22 | Person p1=new Person(); 23 | p1.name="abc"; 24 | p1.flag=false; 25 | 26 | atomic.getAndSet(p1); 27 | 28 | new Thread(()->{ 29 | 30 | Person temp=atomic.get(); 31 | while (!temp.flag){ 32 | 33 | } 34 | System.out.println("my .... end "); 35 | 36 | }).start(); 37 | 38 | try { 39 | Thread.sleep(5000); 40 | } catch (InterruptedException e) { 41 | e.printStackTrace(); 42 | } 43 | 44 | 45 | p1.flag=true; 46 | 47 | System.out.println("main end ....."); 48 | 49 | 50 | // 51 | // System.out.println(pOld); 52 | 53 | } 54 | 55 | 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/concurrent/atomic/AtomicReferenceDemo3.java: -------------------------------------------------------------------------------- 1 | package concurrent.atomic; 2 | 3 | import java.util.concurrent.atomic.AtomicReference; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/5. 7 | */ 8 | public class AtomicReferenceDemo3 { 9 | 10 | 11 | private static AtomicReference tail; 12 | private static AtomicReference tail2=new AtomicReference<>(null); 13 | 14 | 15 | public static void main(String[] args) { 16 | 17 | 18 | System.out.println(tail2.getAndSet("ff")); 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/concurrent/atomic/Person.java: -------------------------------------------------------------------------------- 1 | package concurrent.atomic; 2 | 3 | /** 4 | * Created by Administrator on 2018/7/20. 5 | */ 6 | public class Person { 7 | 8 | private int age; 9 | 10 | public Person(int age) { 11 | this.age = age; 12 | } 13 | 14 | public int getAge() { 15 | return age; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/ReorderingProblem.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | /** 4 | * 重排序问题 5 | */ 6 | public class ReorderingProblem { 7 | 8 | private int a=1; 9 | private boolean flag=true; 10 | 11 | 12 | 13 | private void mthon1(){ 14 | 15 | flag=false; 16 | a=2; 17 | 18 | } 19 | 20 | public void mthon2(){ 21 | if(flag){ 22 | System.out.println(a); 23 | } 24 | } 25 | 26 | 27 | public static void main(String[] args) throws InterruptedException { 28 | 29 | 30 | for (int i = 0; i < 100; i++) { 31 | 32 | ReorderingProblem reorder=new ReorderingProblem(); 33 | 34 | Thread t1=new Thread(()->{ 35 | reorder.mthon1(); 36 | }); 37 | 38 | Thread t2=new Thread(()->{ 39 | reorder.mthon2(); 40 | }); 41 | 42 | t1.start(); 43 | t2.start(); 44 | 45 | 46 | // 如何解决? 47 | 48 | // 使用同步方法 49 | 50 | } 51 | 52 | 53 | 54 | 55 | 56 | } 57 | 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/SynchronizedExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/8. 5 | */ 6 | public class SynchronizedExample { 7 | 8 | 9 | private static volatile int a=3; 10 | 11 | public SynchronizedExample() { 12 | } 13 | 14 | public static synchronized void demo2(){ 15 | 16 | a++; 17 | 18 | } 19 | 20 | public synchronized void demo4(){ 21 | 22 | System.out.println(a); 23 | } 24 | 25 | public void show(){ 26 | 27 | System.out.println(a); 28 | } 29 | 30 | 31 | public void demo1(){ 32 | 33 | //1 34 | 35 | int a=1; 36 | int x=3; 37 | 38 | // 2 39 | synchronized (this){ 40 | int b=5; 41 | StringBuffer buffer=new StringBuffer("abc"); 42 | int c=6; 43 | } 44 | 45 | //3 46 | int e=4; 47 | int y=7; 48 | 49 | } 50 | 51 | 52 | public static void main(String[] args) { 53 | 54 | 55 | 56 | 57 | 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/ThreadGroupDemo.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class ThreadGroupDemo { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | 9 | ThreadGroup threadGroup=new ThreadGroup("test"); 10 | 11 | 12 | Runnable runnable=new Runnable() { 13 | @Override 14 | public void run() { 15 | 16 | System.out.println(Thread.currentThread().getName()+" 开始沉睡 " ); 17 | 18 | try { 19 | TimeUnit.SECONDS.sleep(6); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | 23 | System.out.println(Thread.currentThread().getName()+" 被打断了..... "); 24 | } 25 | 26 | } 27 | }; 28 | 29 | Thread t1=new Thread(threadGroup,runnable,"t1"); 30 | Thread t2=new Thread(threadGroup,runnable,"t2"); 31 | Thread t3=new Thread(threadGroup,runnable,"t3"); 32 | 33 | t1.start(); 34 | t2.start(); 35 | t3.start(); 36 | 37 | Thread.sleep(2000); 38 | 39 | 40 | System.out.println("活动线程数量:" + threadGroup.activeCount()); 41 | 42 | threadGroup.list(); 43 | threadGroup.interrupt(); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/ThreadJoinExample2.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | public class ThreadJoinExample2 { 4 | 5 | 6 | public static void main(String[] args) throws InterruptedException { 7 | 8 | 9 | System.out.println( "123" ); 10 | 11 | //join方法,会阻塞调用者线程,比如在main线程里面,执行t1.join()方法,会阻塞main线程知道t1线程执行完毕 12 | //如果main线程自己调用join方法,那么自己永远存活,对应这个mian线程就会永远不会退出 13 | Thread.currentThread().join(); 14 | 15 | 16 | 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/ThreadStopDemp.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class ThreadStopDemp { 6 | 7 | 8 | public static void main(String[] args) throws InterruptedException { 9 | 10 | 11 | Runnable runnable=new Runnable() { 12 | @Override 13 | public void run() { 14 | 15 | String name=Thread.currentThread().getName(); 16 | while (!Thread.currentThread().isInterrupted()){ 17 | try { 18 | TimeUnit.SECONDS.sleep(2); 19 | System.out.println(name+" 沉睡了2秒...... "); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | // Thread.currentThread().interrupt(); 23 | } 24 | 25 | } 26 | 27 | } 28 | }; 29 | 30 | 31 | Thread thread=new Thread(runnable); 32 | 33 | thread.start(); 34 | 35 | 36 | System.out.println(thread.getThreadGroup()); 37 | 38 | Thread.sleep(4000); 39 | 40 | 41 | 42 | thread.interrupt(); 43 | 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/ThreadYieldExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | /** 4 | * Created by Administrator on 2018/6/26. 5 | */ 6 | public class ThreadYieldExample { 7 | 8 | 9 | public static void main(String[] args) { 10 | 11 | //yield方法仅仅是对线程调度器的一个暗示,表示自己 12 | //可以暂停执行一会,把空闲的资源短暂的让给同一优先级或者更高的线程,如果没有 13 | //符合条件的就还执行自己的任务, 14 | 15 | new Thread(()->{ 16 | 17 | for (int i = 0; i <100; i++) { 18 | 19 | 20 | System.out.println(Thread.currentThread().getName()+" ....."); 21 | 22 | } 23 | 24 | 25 | }).start(); 26 | 27 | 28 | for (int i = 0; i < 100; i++) { 29 | 30 | Thread.yield(); 31 | System.out.println(Thread.currentThread().getName()+" ....."); 32 | 33 | } 34 | 35 | 36 | 37 | 38 | 39 | } 40 | 41 | 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/VariableVisbilityProblem.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | /** 4 | * Created by qindongliang on 2018/6/25. 5 | */ 6 | public class VariableVisbilityProblem { 7 | 8 | static boolean keepRunning=true; 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | 12 | 13 | // 在主线程里面启动一个子线程 14 | new Thread(()->{ 15 | 16 | while (keepRunning){ 17 | 18 | // System.out.println(); 19 | 20 | } 21 | 22 | 23 | }).start(); 24 | 25 | 26 | 27 | Thread.sleep(1000); 28 | //在主线程中改变变量状态 , 循环不会终止 29 | //说明两个线程之间的修改是可见的 30 | keepRunning=false; 31 | 32 | 33 | //println 语句里面是同步的,所以根据happen-before关系是会终止循环的 34 | 35 | // 此外Thread.sleep()方法也会终止,这比较奇怪,因为oracle 36 | //官网明确指出sleep和yield方法没有同步语义,这个问题我暂时 37 | //想不明白,如果你想明白了,请一定告诉我。 38 | 39 | 40 | 41 | 42 | } 43 | 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/concurrent/basic/VariableVisilityProblem2.java: -------------------------------------------------------------------------------- 1 | package concurrent.basic; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/9. 5 | */ 6 | public class VariableVisilityProblem2 { 7 | 8 | private static boolean flag=true; // main thread will call flag=false 9 | 10 | private final static Object lock=new Object(); // lock condition 11 | 12 | public static void thread1(){ 13 | 14 | while (flag){ 15 | 16 | synchronized (lock){ 17 | // some work 18 | } 19 | 20 | } 21 | 22 | } 23 | 24 | 25 | public static void main(String[] args) throws Exception { 26 | 27 | Thread t1=new Thread(()->{ 28 | thread1(); 29 | }); 30 | t1.start(); 31 | Thread.sleep(1000); 32 | flag=false; 33 | 34 | // The program can stop normally 35 | 36 | } 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/concurrent/cas/CasExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.cas; 2 | 3 | import java.util.concurrent.atomic.AtomicBoolean; 4 | 5 | /** 6 | * Created by qindongliang on 2018/7/18. 7 | */ 8 | public class CasExample { 9 | 10 | 11 | private static AtomicBoolean flag=new AtomicBoolean(false); 12 | 13 | public static void main(String[] args) throws InterruptedException { 14 | 15 | 16 | 17 | new Thread(()->{ 18 | 19 | 20 | while (flag.get()){ 21 | 22 | } 23 | 24 | 25 | }).start(); 26 | 27 | 28 | Thread.sleep(2000); 29 | 30 | System.out.println("main end ...."); 31 | 32 | flag.set(false); 33 | 34 | 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/concurrent/live_lock_demo/CommonResource.java: -------------------------------------------------------------------------------- 1 | package concurrent.live_lock_demo; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/15. 5 | */ 6 | public class CommonResource { 7 | 8 | private Worker owner; 9 | 10 | public CommonResource(Worker owner) { 11 | this.owner = owner; 12 | } 13 | 14 | public Worker getOwner() { 15 | return owner; 16 | } 17 | 18 | 19 | public synchronized void setOwner(Worker worker){ 20 | 21 | owner=worker; 22 | 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/concurrent/live_lock_demo/FinalExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.live_lock_demo; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by Administrator on 2018/7/20. 7 | */ 8 | public class FinalExample { 9 | 10 | 11 | static int b=50; 12 | private static int[] array ={0,0,0}; 13 | static int c=60; 14 | public static void main(String[] args) throws InterruptedException { 15 | 16 | 17 | Thread t1=new Thread(()->{ 18 | 19 | 20 | 21 | 22 | while(true){ 23 | 24 | // array.clone(); 25 | if(array[1]==100) { 26 | System.out.println(b+ " "+array[1]+" "+c); 27 | // System.out.println(array[1]); 28 | // System.out.println(c); 29 | break; 30 | } 31 | } 32 | 33 | // array[1]=500; 34 | 35 | System.out.println("end"); 36 | 37 | 38 | 39 | 40 | }); 41 | 42 | 43 | t1.start(); 44 | 45 | Thread.sleep(3000); 46 | b=100; 47 | array[1]=100; 48 | c=200; 49 | // System.out.println(Arrays.toString(array)); 50 | 51 | 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/concurrent/live_lock_demo/LiveLockExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.live_lock_demo; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/15. 5 | * 线程活锁的例子 6 | */ 7 | public class LiveLockExample { 8 | 9 | 10 | public static void main(String[] args) { 11 | 12 | 13 | 14 | Worker w1=new Worker("work1",true); 15 | 16 | 17 | Worker w2=new Worker("work2",true); 18 | 19 | CommonResource common=new CommonResource(w1); 20 | 21 | 22 | new Thread(()->{ 23 | 24 | try { 25 | w1.work(common,w2); 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | 30 | }).start(); 31 | 32 | 33 | 34 | 35 | new Thread(()->{ 36 | 37 | try { 38 | w2.work(common,w1); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | }).start(); 44 | 45 | 46 | } 47 | 48 | 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/concurrent/live_lock_demo/Worker.java: -------------------------------------------------------------------------------- 1 | package concurrent.live_lock_demo; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/15. 5 | */ 6 | public class Worker { 7 | 8 | private String name; 9 | private boolean active; 10 | 11 | public Worker(String name, boolean active) { 12 | this.name = name; 13 | this.active = active; 14 | } 15 | 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public boolean isActive() { 22 | return active; 23 | } 24 | 25 | 26 | public synchronized void work(CommonResource commonResource,Worker otherWorker)throws Exception{ 27 | 28 | while (active){ 29 | 30 | if(commonResource.getOwner()!=this){ 31 | wait(10); 32 | 33 | continue; 34 | } 35 | 36 | 37 | 38 | if(otherWorker.isActive()){ 39 | 40 | 41 | System.out.println(getName()+" 让其他同学先执行:"+otherWorker.getName()); 42 | 43 | commonResource.setOwner(otherWorker); 44 | 45 | Thread.sleep(1000); 46 | continue; 47 | } 48 | 49 | 50 | System.out.println(getName()+"开始使用资源"); 51 | 52 | active=false; 53 | 54 | commonResource.setOwner(otherWorker); 55 | 56 | 57 | } 58 | 59 | 60 | 61 | } 62 | 63 | 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/concurrent/lock/LockExample.java: -------------------------------------------------------------------------------- 1 | package concurrent.lock; 2 | 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | /** 6 | * Created by qindongliang on 2018/7/22. 7 | */ 8 | public class LockExample { 9 | 10 | 11 | public static void main(String[] args) { 12 | 13 | 14 | 15 | ShareCounter counter=new ShareCounter(new ReentrantLock()); 16 | 17 | 18 | Runnable runnable=new Runnable() { 19 | @Override 20 | public void run() { 21 | 22 | try { 23 | System.out.println(Thread.currentThread().getName()+": "+counter.getCount()); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | }; 29 | 30 | 31 | Thread t1=new Thread(runnable,"t1"); 32 | Thread t2=new Thread(runnable,"t2"); 33 | Thread t3=new Thread(runnable,"t3"); 34 | 35 | 36 | t1.start(); 37 | t2.start(); 38 | t3.start(); 39 | 40 | 41 | 42 | 43 | 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/concurrent/lock/LockSupportDemo.java: -------------------------------------------------------------------------------- 1 | package concurrent.lock; 2 | 3 | import java.util.concurrent.locks.LockSupport; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/8. 7 | */ 8 | public class LockSupportDemo { 9 | 10 | 11 | public static void main(String[] args) { 12 | 13 | Thread main=Thread.currentThread(); 14 | 15 | 16 | 17 | 18 | 19 | new Thread(()->{ 20 | 21 | 22 | try { 23 | Thread.sleep(4000); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | 28 | 29 | Object ob= LockSupport.getBlocker(main); 30 | System.out.println(ob); 31 | 32 | }).start(); 33 | 34 | LockSupport.park("dongliangpark"); 35 | 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/concurrent/lock/LockSupportExamle2.java: -------------------------------------------------------------------------------- 1 | package concurrent.lock; 2 | 3 | import java.util.concurrent.locks.LockSupport; 4 | 5 | /** 6 | * Created by Administrator on 2018/8/8. 7 | */ 8 | public class LockSupportExamle2 { 9 | 10 | 11 | public static void main(String[] args) { 12 | 13 | Thread main=Thread.currentThread(); 14 | 15 | new Thread(()->{ 16 | System.out.println("主线程:"+main.getState()); 17 | LockSupport.park("1"); 18 | 19 | System.out.println("主线程:"+main.getState()); 20 | try { 21 | Thread.sleep(5000); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | 26 | System.out.println("5秒后主线程:"+main.getState()); 27 | LockSupport.unpark(main); 28 | 29 | try { 30 | Thread.sleep(2000); 31 | } catch (InterruptedException e) { 32 | e.printStackTrace(); 33 | } 34 | LockSupport.park(main); 35 | System.out.println("解锁后主线程:"+main.getState()); 36 | 37 | }).start(); 38 | 39 | 40 | // LockSupport.park("3"); 41 | 42 | 43 | System.out.println("主线程结束......"); 44 | 45 | 46 | 47 | 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/concurrent/lock/ShareCounter.java: -------------------------------------------------------------------------------- 1 | package concurrent.lock; 2 | 3 | import java.util.concurrent.locks.Lock; 4 | 5 | /** 6 | * Created by qindongliang on 2018/7/22. 7 | */ 8 | public class ShareCounter { 9 | 10 | private Lock lock; 11 | 12 | private int count; 13 | 14 | 15 | public ShareCounter(Lock lock) { 16 | this.lock = lock; 17 | } 18 | 19 | 20 | public int getCount() throws InterruptedException { 21 | 22 | try{ 23 | lock.lock(); 24 | 25 | count++; 26 | return count; 27 | 28 | }finally { 29 | 30 | lock.unlock(); 31 | 32 | } 33 | 34 | 35 | } 36 | 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/concurrent/reorder/ReorderDemo2.java: -------------------------------------------------------------------------------- 1 | package concurrent.reorder; 2 | 3 | /*** 4 | * 5 | * 单线程下重排序,如果破坏了as-if-serial语义, 6 | * 比如下面的代码,虽然a和b没有直接依赖,但是如果b先执行的时候 7 | * 发生了异常,那么a的值是1还是3? 8 | * 实际上是3,发生异常的时候JVM对异常处理机制的重排序做了一种特殊的处理 9 | * 10 | */ 11 | public class ReorderDemo2 { 12 | 13 | 14 | public static void main(String[] args) { 15 | 16 | 17 | int a = 1; 18 | int b = 2; 19 | 20 | try { 21 | a = 3; //A 22 | b = 1 / 0; //B 23 | } catch (Exception e) { 24 | 25 | } finally { 26 | System.out.println("a = " + a); 27 | } 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/concurrent/threadlocal/ThreadLocalExample1.java: -------------------------------------------------------------------------------- 1 | package concurrent.threadlocal; 2 | 3 | /** 4 | * Created by Administrator on 2018/8/6. 5 | */ 6 | public class ThreadLocalExample1 { 7 | 8 | static final ThreadLocal counter=new ThreadLocal(); 9 | 10 | public static void main(String[] args) { 11 | 12 | 13 | Runnable runnable=new Runnable() { 14 | @Override 15 | public void run() { 16 | 17 | for (int i = 0; i <10 ; i++) { 18 | 19 | counter.set(i); 20 | try { 21 | Thread.sleep(1000); 22 | System.out.println(Thread.currentThread().getName()+" 打印"+counter.get() ); 23 | } catch (InterruptedException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | 28 | } 29 | }; 30 | 31 | 32 | 33 | 34 | Thread t1=new Thread(runnable,"线程1"); 35 | Thread t2=new Thread(runnable,"线程2"); 36 | Thread t3=new Thread(runnable,"线程3"); 37 | 38 | 39 | t1.start(); 40 | t2.start(); 41 | t3.start(); 42 | 43 | 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/concurrent/threadpool/ScheduleExecutorServiceTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.threadpool; 2 | 3 | import org.joda.time.DateTime; 4 | 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.ScheduledExecutorService; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * Created by qindongliang on 2018/9/12. 11 | */ 12 | public class ScheduleExecutorServiceTest { 13 | 14 | 15 | public static void main(String[] args) { 16 | 17 | 18 | Runnable runnable=new Runnable() { 19 | @Override 20 | public void run() { 21 | 22 | try { 23 | Thread.sleep(2500); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | 28 | System.out.println(Thread.currentThread().getName()+" running..... "+new DateTime().toString("yyyy-MM-dd HH:mm:ss")); 29 | 30 | } 31 | }; 32 | 33 | 34 | ScheduledExecutorService executor= Executors.newScheduledThreadPool(1); 35 | 36 | 37 | // executor.scheduleAtFixedRate(runnable,2,2, TimeUnit.SECONDS);//等3秒执行 38 | executor.scheduleWithFixedDelay(runnable,2,2, TimeUnit.SECONDS);//等5秒执行 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/concurrent_modify/CopyOnWriteArraySetTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.concurrent_modify; 2 | 3 | import java.util.concurrent.CopyOnWriteArraySet; 4 | 5 | public class CopyOnWriteArraySetTest { 6 | 7 | 8 | public static void main(String[] args) { 9 | 10 | 11 | CopyOnWriteArraySet list=new CopyOnWriteArraySet<>(); 12 | 13 | list.add("b"); 14 | list.add("b"); 15 | list.add("c"); 16 | 17 | System.out.println(list); 18 | 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/countdownlatch/CountDownLatchDemo3.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.countdownlatch; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/24. 7 | */ 8 | public class CountDownLatchDemo3 { 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | 12 | CountDownLatch countDownLatch=new CountDownLatch(3); 13 | 14 | countDownLatch.countDown(); 15 | countDownLatch.countDown(); 16 | countDownLatch.countDown(); 17 | 18 | System.out.println("1111"); 19 | 20 | countDownLatch.await(); 21 | 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/cyclicbarrier/CyclicBarrierDemo3.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.cyclicbarrier; 2 | 3 | import java.util.concurrent.BrokenBarrierException; 4 | import java.util.concurrent.CyclicBarrier; 5 | 6 | /** 7 | * Created by Administrator on 2018/8/23. 8 | */ 9 | public class CyclicBarrierDemo3 { 10 | 11 | 12 | public static void main(String[] args) throws BrokenBarrierException, InterruptedException { 13 | 14 | CyclicBarrier c=new CyclicBarrier(2, new Runnable() { 15 | @Override 16 | public void run() { 17 | 18 | System.out.println(3); 19 | } 20 | }) ; 21 | 22 | 23 | new Thread(()->{ 24 | try { 25 | c.await(); 26 | } catch (InterruptedException e) { 27 | e.printStackTrace(); 28 | } catch (BrokenBarrierException e) { 29 | e.printStackTrace(); 30 | } 31 | System.out.println(1); 32 | 33 | }).start(); 34 | 35 | 36 | c.await(); 37 | 38 | System.out.println(2); 39 | 40 | 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/cyclicbarrier/CyclicBarrierDemo4.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.cyclicbarrier; 2 | 3 | import java.util.concurrent.BrokenBarrierException; 4 | import java.util.concurrent.CyclicBarrier; 5 | 6 | /** 7 | * Created by qindongliang on 2018/8/23. 8 | */ 9 | public class CyclicBarrierDemo4 { 10 | 11 | public static void main(String[] args) { 12 | 13 | 14 | CyclicBarrier cyclicBarrier=new CyclicBarrier(2, new Runnable() { 15 | @Override 16 | public void run() { 17 | System.out.println("任务完成,触发一次....."); 18 | } 19 | }); 20 | 21 | Runnable runnable=new Runnable() { 22 | @Override 23 | public void run() { 24 | try { 25 | Thread.sleep(1000); 26 | cyclicBarrier.await(); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } catch (BrokenBarrierException e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | }; 34 | 35 | 36 | new Thread(runnable).start(); 37 | new Thread(runnable).start(); 38 | 39 | new Thread(runnable).start(); 40 | new Thread(runnable).start(); 41 | 42 | 43 | 44 | 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/cyclicbarrier/CyclicBarrierDemo5.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.cyclicbarrier; 2 | 3 | import java.util.concurrent.BrokenBarrierException; 4 | import java.util.concurrent.CyclicBarrier; 5 | import java.util.concurrent.TimeUnit; 6 | import java.util.concurrent.TimeoutException; 7 | 8 | /** 9 | * Created by qindongliang on 2018/8/24. 10 | */ 11 | public class CyclicBarrierDemo5 { 12 | 13 | public static void main(String[] args) throws InterruptedException, BrokenBarrierException, TimeoutException { 14 | 15 | 16 | CyclicBarrier cyclicBarrier=new CyclicBarrier(2); 17 | 18 | new Thread(()->{ 19 | 20 | try { 21 | cyclicBarrier.await(); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } catch (BrokenBarrierException e) { 25 | e.printStackTrace(); 26 | } 27 | }).start(); 28 | 29 | Thread.sleep(2000); 30 | 31 | System.out.println("1111"); 32 | 33 | cyclicBarrier.await(3, TimeUnit.SECONDS); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/exchager/ExchangeDemo1.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.exchager; 2 | 3 | import java.util.concurrent.Exchanger; 4 | 5 | public class ExchangeDemo1 { 6 | 7 | 8 | 9 | public static void main(String[] args) { 10 | 11 | Exchanger exchanger=new Exchanger(); 12 | ExchangeDemo1 demo1=new ExchangeDemo1(); 13 | 14 | Thread t1=new Thread(new Worker(exchanger,"A")); 15 | Thread t2=new Thread(new Worker(exchanger,"B")); 16 | 17 | t1.start(); 18 | t2.start(); 19 | 20 | } 21 | 22 | 23 | static class Worker implements Runnable{ 24 | 25 | Exchanger exchanger; 26 | Object object; 27 | 28 | public Worker(Exchanger exchanger, Object object) { 29 | this.exchanger = exchanger; 30 | this.object = object; 31 | } 32 | 33 | public void run() { 34 | 35 | Object privious=this.object; 36 | try { 37 | this.object=this.exchanger.exchange(this.object); 38 | System.out.println(Thread.currentThread().getName()+" exchange "+privious+" for "+this.object); 39 | } catch (InterruptedException e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | 44 | } 45 | } 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/map/ConcurrentHashMapTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.map; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | 5 | public class ConcurrentHashMapTest { 6 | 7 | 8 | public static void main(String[] args) { 9 | 10 | 11 | ConcurrentHashMap map=new ConcurrentHashMap<>(2); 12 | 13 | HashMapTest.MyKey m1=new HashMapTest.MyKey("71"); 14 | HashMapTest.MyKey m2=new HashMapTest.MyKey("51"); 15 | HashMapTest.MyKey m3=new HashMapTest.MyKey("31"); 16 | HashMapTest.MyKey m4=new HashMapTest.MyKey("9"); 17 | map.put(m1,"m1"); 18 | map.put(m2,"b1"); 19 | map.put(m3,"b2"); 20 | map.put(m4,"m4"); 21 | 22 | System.out.println(map); 23 | 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/map/HashMapTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.map; 2 | 3 | import java.util.HashMap; 4 | 5 | public class HashMapTest { 6 | 7 | static public class MyKey { 8 | String key; 9 | 10 | public MyKey(String key) { 11 | this.key = key; 12 | } 13 | 14 | @Override 15 | public int hashCode() { 16 | if(key.endsWith("1")){ 17 | return 1; 18 | } 19 | return super.hashCode(); 20 | } 21 | } 22 | 23 | 24 | public static void main(String[] args) { 25 | 26 | 27 | HashMap map=new HashMap<>(4); 28 | 29 | MyKey m1=new MyKey("71"); 30 | MyKey m2=new MyKey("51"); 31 | MyKey m3=new MyKey("31"); 32 | MyKey m4=new MyKey("9"); 33 | map.put(m1,"m1"); 34 | map.put(m2,"m2"); 35 | map.put(m3,"m3"); 36 | map.put(m4,"m4"); 37 | 38 | System.out.println(map.toString()); 39 | 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/map/LinkedHashMapTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.map; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | public class LinkedHashMapTest { 6 | 7 | public static void main(String[] args) { 8 | 9 | // (1) 维护了插入数据的顺序 10 | // (2) 可以通过按访问顺序排序,如下声明,第三个参数控制 11 | LinkedHashMap map = new LinkedHashMap(16,0.75f,true); 12 | map.put("21",1) ; 13 | map.put("12",2) ; 14 | map.put("3",3) ; 15 | map.put("74",4) ; 16 | map.put("75",5) ; 17 | 18 | // 19 | 20 | System.out.println(map.toString()); 21 | 22 | 23 | System.out.println(map.get("21")); 24 | System.out.println(map.get("3")); 25 | 26 | System.out.println(map.toString()); 27 | 28 | 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/map/TreeMapTest.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.map; 2 | 3 | import java.util.TreeMap; 4 | 5 | public class TreeMapTest { 6 | 7 | public static void main(String[] args) { 8 | 9 | //基于红黑树的实现 10 | TreeMap map=new TreeMap<>(); 11 | 12 | map.put("a12",1); 13 | map.put("d6",11); 14 | map.put("a2",12); 15 | map.put("b2",3); 16 | 17 | 18 | System.out.println(map); 19 | 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/phaser/PhaserDemo2.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.phaser; 2 | 3 | 4 | import java.util.concurrent.Phaser; 5 | 6 | /** 7 | * Created by qindongliang on 2018/8/26. 8 | */ 9 | public class PhaserDemo2 { 10 | 11 | public static void main(String[] args) { 12 | 13 | int stepNums=3; 14 | 15 | Phaser phaser=new Phaser(){ 16 | 17 | @Override 18 | protected boolean onAdvance(int phase, int registeredParties) { 19 | System.out.println(phase+" "+registeredParties); 20 | return phase+1>=stepNums||registeredParties==0; 21 | } 22 | }; 23 | 24 | 25 | 26 | for (int i = 0; i < 4; i++) { 27 | phaser.register(); 28 | new Thread(new Task2(phaser)).start(); 29 | 30 | } 31 | 32 | 33 | } 34 | 35 | 36 | static class Task2 implements Runnable{ 37 | private final Phaser phaser; 38 | 39 | public Task2(Phaser phaser) { 40 | this.phaser = phaser; 41 | } 42 | 43 | @Override 44 | public void run() { 45 | 46 | //判断是否终止 47 | while (!phaser.isTerminated()){ 48 | int i=phaser.arriveAndAwaitAdvance(); 49 | System.out.println(Thread.currentThread().getName()+"执行完任务"); 50 | } 51 | 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/phaser/PhaserDemo6.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.phaser; 2 | 3 | import java.util.concurrent.Phaser; 4 | 5 | /** 6 | * Created by Administrator on 2018/8/27. 7 | */ 8 | public class PhaserDemo6 { 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | 12 | final Phaser phaser=new Phaser(1); 13 | 14 | 15 | Runnable runnable=new Runnable() { 16 | @Override 17 | public void run() { 18 | try { 19 | Thread.sleep(1000); 20 | } catch (InterruptedException e) { 21 | e.printStackTrace(); 22 | } 23 | phaser.arriveAndAwaitAdvance();//等待 24 | 25 | System.out.println(Thread.currentThread().getName()+" 开始执行。。 "); 26 | 27 | } 28 | }; 29 | 30 | for (int i = 0; i < 3; i++) { 31 | phaser.register(); 32 | new Thread(runnable).start(); 33 | } 34 | Thread.sleep(6000); 35 | // phaser.arriveAndAwaitAdvance(); 36 | phaser.arriveAndDeregister(); 37 | System.out.println(Thread.currentThread().getName()+" 开始执行。。 "); 38 | 39 | 40 | 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/phaser/PhraseDemo3.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.phaser; 2 | 3 | import java.util.concurrent.Phaser; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/26. 7 | */ 8 | public class PhraseDemo3 { 9 | 10 | public static void main(String[] args) { 11 | 12 | Phaser phaser=new Phaser(2); 13 | 14 | for (int i = 0; i < 2; i++) { 15 | new Thread(new Worker(phaser)).start(); 16 | } 17 | 18 | 19 | } 20 | 21 | static class Worker implements Runnable{ 22 | 23 | private final Phaser phaser; 24 | 25 | public Worker(Phaser phaser) { 26 | this.phaser = phaser; 27 | } 28 | 29 | @Override 30 | public void run() { 31 | String name=Thread.currentThread().getName(); 32 | System.out.println(name+" 执行完成..... "); 33 | 34 | phaser.arriveAndAwaitAdvance(); 35 | System.out.println(name+"继续执行......"); 36 | } 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/concurrent/tools/semaphore/SemaphoreDemo1.java: -------------------------------------------------------------------------------- 1 | package concurrent.tools.semaphore; 2 | 3 | import java.util.concurrent.Semaphore; 4 | import java.util.concurrent.locks.Lock; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | /** 8 | * Created by Administrator on 2018/8/24. 9 | */ 10 | public class SemaphoreDemo1 { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | 14 | Semaphore semaphore=new Semaphore(3); 15 | 16 | Runnable runnable=new Runnable() { 17 | @Override 18 | public void run() { 19 | try { 20 | semaphore.acquire(); 21 | Thread.sleep(3000); 22 | } catch (InterruptedException e) { 23 | e.printStackTrace(); 24 | } 25 | System.out.println(Thread.currentThread().getName() + " 访问资源......"); 26 | semaphore.release(); 27 | } 28 | }; 29 | 30 | for (int i = 0; i < 5; i++) { 31 | Thread thread=new Thread(runnable); 32 | thread.start(); 33 | } 34 | 35 | Thread.sleep(3000); 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/data_structure/b_tree/Btree.java: -------------------------------------------------------------------------------- 1 | package data_structure.b_tree; 2 | 3 | /*** 4 | * https://www.cnblogs.com/dongguacai/p/7239599.html 5 | * https://www.cnblogs.com/dongguacai/p/7241860.html 6 | */ 7 | public class Btree { 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/data_structure/binary_tree/L-6_2-3_Trees.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/java/data_structure/binary_tree/L-6_2-3_Trees.pdf -------------------------------------------------------------------------------- /src/main/java/data_structure/binary_tree/Tree23.java: -------------------------------------------------------------------------------- 1 | package data_structure.binary_tree; 2 | 3 | public class Tree23> { 4 | 5 | 6 | public static void main(String[] args) { 7 | 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo1/CallBack.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo1; 2 | 3 | public interface CallBack { 4 | 5 | void methodToCallBack(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo1/CallBackImpl.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo1; 2 | 3 | public class CallBackImpl implements CallBack { 4 | 5 | @Override 6 | public void methodToCallBack() { 7 | System.out.println(" i have been called back"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo1/Caller.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo1; 2 | 3 | 4 | 5 | public class Caller { 6 | 7 | 8 | private void registed(CallBack callBack){ 9 | callBack.methodToCallBack(); 10 | } 11 | 12 | 13 | public void work(String task,CallBack callBack){ 14 | 15 | System.out.println("任务执行完了"); 16 | 17 | callBack.methodToCallBack(); 18 | 19 | } 20 | 21 | 22 | public static void main(String[] args) { 23 | 24 | Caller caller=new Caller(); 25 | 26 | CallBack callback=new CallBackImpl();// instance callback 27 | 28 | caller.work("execute task",callback); 29 | 30 | 31 | 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo2/AppMain.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo2; 2 | 3 | public class AppMain { 4 | 5 | public static void main(String[] args) throws InterruptedException { 6 | 7 | Student student=new Student();//学生角色 8 | 9 | System.out.println("\n===============同步模式================"); 10 | Teacher teacher=new Teacher(student);//老师角色 11 | //同步回调模式,老师给学生布置作业,老师等学生完成之后才能回家 12 | teacher.assignWork(true); 13 | 14 | System.out.println("\n===============异步模式================"); 15 | //异步回调模式,老师给学生布置作业,布置完成之后就可以回家,学生完成之后会通知老师查看。 16 | teacher.assignWork(false); 17 | 18 | 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo2/CallBack.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo2; 2 | 3 | /*** 4 | *通过接口定义回调函数 5 | */ 6 | public interface CallBack { 7 | //检查作业属于老师的功能,但由学生触发,故称回调 8 | public void checkWork(); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo2/Student.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo2; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class Student { 6 | 7 | 8 | public void doWrok(CallBack callBack) throws InterruptedException { 9 | System.out.println("学生开始做作业....."); 10 | TimeUnit.SECONDS.sleep(3); 11 | System.out.println("学生完成作业了,通知老师查看"); 12 | callBack.checkWork(); //通知老师查看作业 13 | } 14 | 15 | 16 | public void asynDoWrok(CallBack callBack) throws InterruptedException { 17 | //通过一个线程来异步的执行任务 18 | Runnable runnable= new Runnable(){ 19 | @Override 20 | public void run() { 21 | System.out.println("学生开始做作业....."); 22 | try { 23 | TimeUnit.SECONDS.sleep(3); 24 | } catch (InterruptedException e) { 25 | e.printStackTrace(); 26 | } 27 | System.out.println("学生完成作业了,通知老师查看"); 28 | callBack.checkWork(); 29 | } 30 | }; 31 | 32 | Thread thread=new Thread(runnable); 33 | thread.start(); 34 | 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/callback/demo2/Teacher.java: -------------------------------------------------------------------------------- 1 | package design_pattern.callback.demo2; 2 | 3 | public class Teacher implements CallBack { 4 | 5 | private Student student; 6 | 7 | public Teacher(Student student) { 8 | this.student = student; 9 | } 10 | 11 | /*** 12 | * 给学生分配作业 13 | * @param isSync true=同步回调 false=异步回调 14 | * @throws InterruptedException 15 | */ 16 | public void assignWork(boolean isSync) throws InterruptedException { 17 | System.out.println("老师分配作业完成...."); 18 | if(isSync){ 19 | student.doWrok(this);//同步通知做作业 20 | }else{ 21 | student.asynDoWrok(this);//异步通知做作业 22 | } 23 | System.out.println("老师回家了...."); 24 | } 25 | 26 | 27 | @Override 28 | public void checkWork() { 29 | System.out.println("老师收到通知并查看了学生的作业!"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/singleton/create/DoubleCheckSingleton.java: -------------------------------------------------------------------------------- 1 | package design_pattern.singleton.create; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/4. 5 | * 6 | * 基于延迟加载的使用双检锁的单例模式 7 | * 8 | */ 9 | public class DoubleCheckSingleton { 10 | 11 | 12 | private volatile static DoubleCheckSingleton instance; 13 | 14 | //私有的构造方法 15 | private DoubleCheckSingleton() { 16 | } 17 | 18 | /*** 19 | * 基于双检锁模式获取单例 20 | * @return 21 | */ 22 | public static DoubleCheckSingleton getInstance(){ 23 | 24 | if(instance==null){ //第一层检查 25 | 26 | synchronized (DoubleCheckSingleton.class){ 27 | 28 | if(instance==null){ //第二层检查 29 | 30 | instance=new DoubleCheckSingleton(); 31 | 32 | } 33 | 34 | } 35 | 36 | } 37 | 38 | return instance; 39 | 40 | } 41 | 42 | 43 | /*** 44 | * 基于同步方法的单例模式 45 | * @return 46 | */ 47 | public synchronized static DoubleCheckSingleton getInstanceBySync(){ 48 | 49 | if (instance==null){ 50 | instance=new DoubleCheckSingleton(); 51 | } 52 | return instance; 53 | 54 | } 55 | 56 | 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/singleton/create/SimpleSingleton.java: -------------------------------------------------------------------------------- 1 | package design_pattern.singleton.create; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/5. 5 | */ 6 | public class SimpleSingleton { 7 | 8 | private final static SimpleSingleton ourInstance = new SimpleSingleton(); 9 | 10 | private SimpleSingleton() { 11 | } 12 | 13 | public static SimpleSingleton getInstance() { 14 | return ourInstance; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/singleton/create/StaicNestedSingleton.java: -------------------------------------------------------------------------------- 1 | package design_pattern.singleton.create; 2 | 3 | /** 4 | * Created by qindongliang on 2018/7/5. 5 | */ 6 | public class StaicNestedSingleton { 7 | 8 | private StaicNestedSingleton() { 9 | } 10 | 11 | public static StaicNestedSingleton get() { 12 | return Holder.instance; 13 | } 14 | 15 | private static class Holder { 16 | public static final StaicNestedSingleton instance = new StaicNestedSingleton(); 17 | } 18 | 19 | 20 | 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/design_pattern/singleton/destroy_singly/Singleton.java: -------------------------------------------------------------------------------- 1 | package design_pattern.singleton.destroy_singly; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Singleton implements Serializable,Cloneable { 6 | 7 | //在类初始化期间,执行由JVM保证线程安全 8 | private static Singleton singleton=new Singleton(); 9 | 10 | 11 | //避免反射和多类加载器破坏 12 | private Singleton() { 13 | if (Singleton.singleton != null) { 14 | throw new InstantiationError("Creating of this object is not allowed."); 15 | } 16 | 17 | } 18 | 19 | public static Singleton getInstance(){ 20 | return singleton; 21 | } 22 | 23 | //避免克隆破坏 24 | @Override 25 | protected Object clone() throws CloneNotSupportedException { 26 | throw new CloneNotSupportedException("Cloning of this class is not allowed"); 27 | // return super.clone(); 28 | } 29 | 30 | // //避免反序列破坏 31 | protected Object readResolve() { 32 | return singleton; 33 | } 34 | 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/gc/Demo.java: -------------------------------------------------------------------------------- 1 | package gc; 2 | 3 | public class Demo { 4 | 5 | private Object instance; 6 | 7 | public static void main(String[] args) { 8 | //引用计数器的垃圾回收思想,对于本身之间相互引用如下,可能没法回收,但其实他们已经无用了 9 | Demo a=new Demo(); 10 | Demo b=new Demo(); 11 | a.instance=b; 12 | b.instance=a; 13 | a=null; 14 | b=null; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/io/io_model/v3_aio/CustomAttachment.java: -------------------------------------------------------------------------------- 1 | package io.io_model.v3_aio; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.channels.AsynchronousServerSocketChannel; 5 | import java.nio.channels.AsynchronousSocketChannel; 6 | 7 | public class CustomAttachment { 8 | 9 | private AsynchronousServerSocketChannel server; 10 | private AsynchronousSocketChannel client; 11 | private boolean isReadMode; 12 | private ByteBuffer buffer; 13 | 14 | public AsynchronousServerSocketChannel getServer() { 15 | return server; 16 | } 17 | 18 | public void setServer(AsynchronousServerSocketChannel server) { 19 | this.server = server; 20 | } 21 | 22 | public AsynchronousSocketChannel getClient() { 23 | return client; 24 | } 25 | 26 | public void setClient(AsynchronousSocketChannel client) { 27 | this.client = client; 28 | } 29 | 30 | public boolean isReadMode() { 31 | return isReadMode; 32 | } 33 | 34 | public void setReadMode(boolean readMode) { 35 | isReadMode = readMode; 36 | } 37 | 38 | public ByteBuffer getBuffer() { 39 | return buffer; 40 | } 41 | 42 | public void setBuffer(ByteBuffer buffer) { 43 | this.buffer = buffer; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/BestTimeSellStock.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | *卖股票,找到收益最大的价格 5 | * https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 6 | */ 7 | public class BestTimeSellStock { 8 | public int maxProfit(int[] prices) { 9 | int ans=0; 10 | if(prices.length==0){ 11 | return ans; 12 | } 13 | int bougt=prices[0]; 14 | for (int i = 1; i bougt){ 17 | ans=Math.max(ans,prices[i]-bougt); 18 | }else { 19 | bougt=prices[i]; 20 | } 21 | } 22 | 23 | 24 | return ans; 25 | } 26 | 27 | public static void main(String[] args) { 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/BestTimeSellStockII.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | //https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 3 | public class BestTimeSellStockII { 4 | 5 | public static int maxProfit(int[] prices) { 6 | int profit=0; 7 | for (int i = 1; i 0){ 21 | profit+=diff; 22 | } 23 | prev=price; 24 | 25 | } 26 | return profit; 27 | } 28 | 29 | 30 | 31 | public static void main(String[] args) { 32 | int []arr={7,1,5,3,6,4}; 33 | System.out.println(maxProfit(arr)); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/CanPlaceFlowers.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * https://leetcode.com/problems/can-place-flowers/ 5 | * 6 | * 给定一个int数组,代表花罐子,里面的数值只能是0或者1,0代表空,1代表有花 7 | * 只有两个0之间才能种花,如果两个1挨着,会导致他们争夺水资源导致死亡。 8 | * 现在给定一个花罐数组,并给出新种的花的个数,让求出,这个罐子中能不能放的下新增的花。 9 | * 10 | * 思路: 11 | * 12 | * 循环数组,初始化情况下count=1,然后对连续0计数,如果遇到非0,就count-1的结果除以2,就是能中的颗数, 13 | * 直到循环结束,最后在除以2,看商是否大于等于n,如果满足,则可以中下。 14 | */ 15 | public class CanPlaceFlowers { 16 | public static boolean canPlaceFlowers(int[] flowerbed, int n) { 17 | 18 | int count = 1; 19 | int result = 0; 20 | for(int i=0; i=n; 30 | } 31 | public static void main(String[] args) { 32 | int arr[]={0,0}; 33 | System.out.println(canPlaceFlowers(arr,1)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/ContainsDuplicate.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | //https://leetcode.com/problems/contains-duplicate/ 6 | public class ContainsDuplicate { 7 | public static boolean containsDuplicate1(int[] nums) { 8 | Set set=new HashSet<>(2*nums.length); 9 | for (int num:nums){ 10 | if(!set.add(num)){ 11 | return true; 12 | } 13 | } 14 | return false; 15 | } 16 | 17 | 18 | 19 | public static void main(String[] args) { 20 | 21 | int []arr={1,2,3,1}; 22 | System.out.println(containsDuplicate1(arr)); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/ContainsDuplicateII.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /**** 7 | * 8 | * 题目描述: 9 | * 10 | * 给定一个int数组,并给定一个k距离值,让你判断,是否存在两个下标i和j,他们的nums[i]=nums[j], 11 | * 并且i和j的绝对值最大为k,如果存在就返回true,否则就返回false 12 | * 13 | * 思路: 14 | * 借用滑动窗口的思路,遍历整个数组,始终将窗口值保持在k范围之内,然后判断是否有符合条件的 15 | * 数据,有就有返回true,如果遍历结束都没有,就返回false。 16 | * 17 | */ 18 | 19 | public class ContainsDuplicateII { 20 | 21 | public static boolean containsNearbyDuplicate(int[] nums, int k) { 22 | 23 | Set set=new HashSet<>(); 24 | for (int i = 0; i < nums.length; i++) { 25 | //如果i的值大于k,就移除掉在窗口距离k之外的数据 26 | if(i>k){ 27 | set.remove(nums[i-k-1]); 28 | } 29 | //然后判断在窗口值范围内是否存在我们要找的数据,如果出现两次就返回true 30 | if(!set.add(nums[i])){//不包含返回true 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | public static void main(String[] args) { 38 | int arr[]={1,0,1,1}; 39 | int k=1; 40 | 41 | System.out.println(containsNearbyDuplicate(arr,k)); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/FibonacciNumber.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * https://leetcode.com/problems/fibonacci-number/ 5 | * 斐波那契数列的迭代版本和递归版本 6 | */ 7 | public class FibonacciNumber { 8 | 9 | public static int fib(int N) { 10 | if(N<=1){ 11 | return N; 12 | } 13 | 14 | int a=0; 15 | int b=1; 16 | while (N-->1){ 17 | int sum=a+b; 18 | a=b; 19 | b=sum; 20 | } 21 | return b; 22 | } 23 | 24 | 25 | 26 | 27 | public static int fib2(int N) { 28 | if(N<=1){ 29 | return N; 30 | } 31 | return fib2(N-1)+fib2(N-2); 32 | } 33 | 34 | 35 | public static void main(String[] args) { 36 | System.out.println(fib(10)); 37 | System.out.println(fib2(10)); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/FindDiappearedInArray.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | /* 6 | *给定一个数组,数组里面值的大小范围是 1<=a[i]<=array.length,数组里面的 7 | *值,可以重复的出现一次或者两次,现在让求出不在数组里面的的元素列表。 8 | */ 9 | public class FindDiappearedInArray { 10 | 11 | public static List findDisappearedNumbers(int[] nums) { 12 | 13 | List result=new ArrayList<>(); 14 | for (int i = 0; i < nums.length; i++) { 15 | int index=Math.abs(nums[i])-1; 16 | if(nums[index]>0) { 17 | nums[index] = -nums[index]; 18 | } 19 | } 20 | 21 | for (int i=0;i0){ 23 | result.add(i+1); 24 | } 25 | } 26 | return result; 27 | } 28 | 29 | public static void main(String[] args) { 30 | int arr[]={4,3,2,7,8,2,3,1};//5,6 31 | System.out.println(findDisappearedNumbers(arr)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/FindPivotIndex.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * 5 | * 题目描述:给定一个数组,让找出一个基准index,使得左半数字的和等于右半部分的和 6 | * 不包括基准数字。 7 | * 8 | * 解题思路: 9 | * 10 | * 先循环一次求出数组的总和。 11 | * 12 | * 然后再循环一次,从后一位开始,才统计前一位数字,使用一个left变量,来存储左半部分的和 13 | * 然后每一次判断左半部分的和,是否与sum-left-arr[i]也就是右半部分的和相等,如果相等 14 | * 就返回index,也就是我们要找的pivot 15 | */ 16 | public class FindPivotIndex { 17 | 18 | 19 | public static int pivotIndex(int[] nums) { 20 | int sum=0; 21 | int left=0; 22 | for (int num:nums){ 23 | sum+=num; 24 | } 25 | 26 | for (int i = 0; i < nums.length; i++) { 27 | if(i!=0){ 28 | left+=nums[i-1]; 29 | } 30 | if(sum-left-nums[i]==left){ 31 | return i; 32 | } 33 | } 34 | return -1; 35 | 36 | } 37 | 38 | public static void main(String[] args) { 39 | int arr[]={1, 7, 3, 6, 5, 6}; 40 | System.out.println(pivotIndex(arr)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/HeightChecker.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * 题目连接:https://leetcode.com/problems/height-checker/ 5 | * 题目描述: 6 | * 给定一个int数组代表一个班的学生,希望是按照学生的身高来从低到高排序,现在站的队形可能是不对的 7 | * 让求出有多少个站的位置是不对的,返回统计的人数。 8 | * 解题思路: 9 | * 这道题其实很容易,最简单的思路就是对数组进行排序,然后对比新数组与原数组位置上数字不同的个数 10 | * 有多少个,当然排序这个我们可以借助计数排序来实现。 11 | * 12 | */ 13 | public class HeightChecker { 14 | 15 | public static int heightChecker(int[] heights) { 16 | 17 | int []heightToFreq=new int[101]; 18 | for (int height:heights){ 19 | heightToFreq[height]++; 20 | } 21 | 22 | int result=0; 23 | int curHeight=0; 24 | for (int i = 0; i < heights.length; i++) { 25 | while (heightToFreq[curHeight]==0){ 26 | curHeight++; 27 | } 28 | 29 | if(curHeight!=heights[i]){ 30 | result++; 31 | } 32 | 33 | heightToFreq[curHeight]--; 34 | } 35 | return result; 36 | } 37 | 38 | public static void main(String[] args) { 39 | int arr[]={1,1,4,2,1,3}; 40 | System.out.println(heightChecker(arr)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/KdiffPairs.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /**** 7 | * 8 | * 题目描述:https://leetcode.com/problems/k-diff-pairs-in-an-array/ 9 | * 给定一个int数组,并给定一个数字k,然后求出这个数组里面,有多少对唯一的两个数字 10 | * 相减的和等于k,返回这个数字。 11 | * 例如:[3, 1, 4, 1, 5], k = 2 12 | * 这里面返回的就2对,(1,3)和 (3,5) 13 | */ 14 | public class KdiffPairs { 15 | 16 | public static int findPairs(int[] nums, int k) { 17 | 18 | if(nums==null||nums.length==0||k<0) return 0; 19 | 20 | Map map=new HashMap<>(); 21 | int count=0; 22 | for (int i:nums){ 23 | map.put(i,map.getOrDefault(i,0)+1); 24 | } 25 | 26 | for(Map.Entry kv:map.entrySet()){ 27 | if(k==0){ 28 | if(kv.getValue()>=2){ 29 | count++; 30 | } 31 | }else { 32 | if(map.containsKey(kv.getKey()+k)){ 33 | count++; 34 | } 35 | } 36 | } 37 | return count; 38 | } 39 | 40 | public static void main(String[] args) { 41 | 42 | int arr[]={1, 3, 1, 5, 4}; 43 | int k=0; 44 | System.out.println(findPairs(arr,k)); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/KindDeckCards.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /**** 7 | * https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/ 8 | * 给定一组卡牌,让求出里面相同数字的所有分组,分组的数量不得小于2 9 | * 10 | * 思路:遍历一遍数组,求出每个数字的数量 11 | * 然后,对数量之间求出最大公约数,最后如果最大公约数2即可。 12 | */ 13 | public class KindDeckCards { 14 | 15 | public static boolean hasGroupsSizeX(int[] deck) { 16 | Map count=new HashMap<>(); 17 | for (int i :deck) { 18 | count.put(i,count.getOrDefault(i,0)+1); 19 | } 20 | int res=0; 21 | for (int i:count.values()){ 22 | res=gcd(i,res); 23 | } 24 | 25 | return res>1; 26 | } 27 | 28 | //最大公约数算法->辗转相除法 29 | public static int gcd(int a, int b){ 30 | if(b==0){ 31 | return a; 32 | } 33 | return gcd(b,a%b); 34 | } 35 | 36 | 37 | public static void main(String[] args) { 38 | int arr[]={0,0,0,1,1,1,2,2,2}; 39 | System.out.println(hasGroupsSizeX(arr)); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/LargeGroups.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /*** 8 | * https://leetcode.com/problems/positions-of-large-groups/ 9 | * 题目描述:给定一个小写字符串,找出里面连续出现大于等于3次的所有字符 10 | * 并记录开始出现的index,和结束的index,存进一个list里面返回。 11 | * 12 | *思路: 13 | * 14 | * 采用双指针法进行遍历,如果当i和start的value不等的时候,就判断是否符合条件 15 | * 然后重置start的位置,用来记录新的字符 16 | */ 17 | public class LargeGroups { 18 | public static List> largeGroupPositions(String s) { 19 | 20 | List> result=new ArrayList<>(); 21 | int start=0; 22 | for (int i = 1; i <= s.length(); i++) { 23 | if(i==s.length()||s.charAt(i)!=s.charAt(start)){ 24 | if(i-start>=3){ 25 | result.add(Arrays.asList(start,i-1)); 26 | } 27 | start=i; 28 | } 29 | } 30 | 31 | return result; 32 | } 33 | 34 | public static void main(String[] args) { 35 | 36 | String test="abcdddeeeeaabbbcd"; 37 | 38 | System.out.println(largeGroupPositions(test)); 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/LargestNumberTwice.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * https://leetcode.com/problems/largest-number-at-least-twice-of-others/ 5 | * 题目描述:给定一个int数组,找出是否存在一个最大值数字,其值是第二大数字的两倍 6 | * 7 | * 思路: 8 | * 9 | * 声明两个变量保留,最大值和次大值,循环的时候求出并赋值, 10 | * 直到遍历结束,判断次大值的两倍是否小于等于最大值 11 | * 12 | */ 13 | 14 | public class LargestNumberTwice { 15 | 16 | public static int dominantIndex(int[] nums) { 17 | int max=-1; 18 | int index=-1; 19 | int second=-1; 20 | for (int i = 0; i < nums.length; i++) { 21 | if(nums[i]>max){ 22 | second=max; 23 | max=nums[i]; 24 | index=i; 25 | }else if(nums[i]>second){ 26 | second=nums[i]; 27 | } 28 | } 29 | return second*2<=max?index:-1; 30 | 31 | } 32 | 33 | public static void main(String[] args) { 34 | 35 | int arr[]={3, 6, 1, 0}; 36 | 37 | System.out.println(dominantIndex(arr)); 38 | 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/LongestContinuousSubsequence.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * https://leetcode.com/problems/longest-continuous-increasing-subsequence/ 5 | * 6 | * 题目描述:找出数组里面连续自增的最大长度 7 | * 比如 [1,3,5,4,7],连续自增的长度是1,3,5 所以长度为3 8 | * 9 | */ 10 | public class LongestContinuousSubsequence { 11 | 12 | public static int findLengthOfLCIS(int[] nums) { 13 | if(nums.length==0) return 0; 14 | int max=1; 15 | int count=1; 16 | //从1开始遍历,直接与后面的比较 17 | for (int i = 1; i < nums.length; i++) { 18 | //如果大于前一位,那么就是自增,所以计数+1 19 | if(nums[i]>nums[i-1]){ 20 | count++; 21 | //如果自增大于最大值,就赋值最大值 22 | if(count>max){ 23 | max=count; 24 | } 25 | }else { 26 | count=1;//重置为1 27 | } 28 | } 29 | 30 | return max; 31 | 32 | } 33 | 34 | 35 | public static void main(String[] args) { 36 | int arr[]={1,3,5,4,7}; 37 | System.out.println(findLengthOfLCIS(arr)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/MajorityElement.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | //找出数组里面多于数组size一半重复的数字,叫大多数数字 3 | public class MajorityElement { 4 | public static int majorityElement(int[] nums) { 5 | 6 | int count=0; 7 | int major=nums[0]; 8 | for (int element:nums) { 9 | if(count==0){ 10 | major=element; 11 | count++; 12 | }else if(element==major){ 13 | count++; 14 | }else { 15 | count--; 16 | } 17 | } 18 | 19 | return major; 20 | } 21 | 22 | 23 | 24 | public static void main(String[] args) { 25 | // int arr[]={2,2,1,1,1,2,2}; 26 | int arr[]={6,5,5}; 27 | System.out.println(majorityElement(arr)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/MatrixDiagonal.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /**** 4 | * https://leetcode.com/problems/toeplitz-matrix/ 5 | */ 6 | public class MatrixDiagonal { 7 | 8 | 9 | public static boolean isToeplitzMatrix(int[][] matrix) { 10 | 11 | for (int i = 0; i < matrix.length-1; i++) { 12 | for (int j = 0; j max){ 28 | max=sum; 29 | } 30 | 31 | } 32 | return max; 33 | } 34 | 35 | public static void main(String[] args) { 36 | int arr[]={-2,1,-3,4,-1,2,1,-5,4}; 37 | System.out.println(maxSubArray(arr)); 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/MinCostClimbingStairs.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | public class MinCostClimbingStairs { 4 | public static int minCostClimbingStairs(int[] cost) { 5 | for (int i = 2; i nums[i+1]){ 20 | count++; 21 | if(count==2) return false; 22 | if(i>0&&nums[i+1]> generate(int numRows) { 13 | 14 | List> allRows=new ArrayList<>(); 15 | 16 | ArrayList row=new ArrayList<>(); 17 | for (int i = 0; i < numRows; i++) { 18 | row.add(0,1); 19 | for (int j = 1; j (row)); 23 | } 24 | 25 | 26 | return allRows; 27 | } 28 | 29 | public static void main(String[] args) { 30 | 31 | List> result= generate(3); 32 | 33 | for(List list:result){ 34 | System.out.println(list); 35 | } 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/RemoveDuplicateSortedArray.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.Arrays; 4 | 5 | /**** 6 | *https://leetcode.com/problems/remove-duplicates-from-sorted-array/ 7 | * 题目描述: 8 | * 9 | * 给定一个可以重复的有序数组,让在不额外花费空间的前提下,对数组进行去重, 10 | * 把不重复的数字在原有的数组中修改顺序,最终返回数组的长度 11 | * 12 | * 思路: 13 | * 总体来说比较简单,我们只需要遍历数组一次即可, 14 | * 15 | * 用额外的从0开始的一个变量,用来标记当前不重复数组已经更新的位置 16 | * 当遇到相邻不相等的时候,就把j的值+1,然后把i位置的值给赋值给 17 | * j,直到遍历数组结束即可 18 | * 19 | */ 20 | 21 | public class RemoveDuplicateSortedArray { 22 | public static int removeDuplicates(int[] nums) { 23 | if(nums.length==0){ return 0;} 24 | int j=0; 25 | for (int i = 1; i =0 ;i--) { 14 | a=arr[i]; 15 | arr[i]=mx; 16 | mx=Math.max(mx,a);//获取右边出现最大的值 17 | } 18 | 19 | return arr; 20 | 21 | 22 | 23 | 24 | } 25 | 26 | 27 | public static void main(String[] args) { 28 | 29 | System.out.println(Arrays.toString(replaceElements(new int[]{17,18,5,4,6,1}))); 30 | //[18, 6, 6, 6, 1, -1] 31 | // 32 | 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/ReshapeMartix.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /*** 4 | * 5 | * nums = 6 | * [[1,2], 7 | * [3,4]] 8 | * r = 1, c = 4 9 | * Output: 10 | * [[1,2,3,4]] 11 | * 12 | * 思路: 13 | * 代码参考网上分享的方式,比较巧妙,一般人可能想不到,并且比较简单 14 | * 15 | * 观察代码发现,对于一个二维数组,元素总量m =row * col 16 | *其实每一个元素的坐标是等于从0到m之间的,任意一个遍历的数字 17 | * 除以col=得到row,与col求模得到col,比较巧妙 18 | * 19 | */ 20 | public class ReshapeMartix { 21 | 22 | 23 | public static int[][] matrixReshape(int[][] nums, int r, int c) { 24 | 25 | int rowOld=nums.length; //row length 26 | int colOld=nums[0].length;// col length 27 | if(r*c!=rowOld*colOld){ 28 | return nums; 29 | } 30 | 31 | int [][]res=new int[r][c]; 32 | 33 | for (int i = 0; i < r*c; i++) { 34 | System.out.println("new=["+i/c+","+i%c+"], old=["+i/colOld+","+i%colOld+"]"); 35 | res[i/c][i%c]=nums[i/colOld][i%colOld]; 36 | } 37 | 38 | return res; 39 | 40 | } 41 | 42 | public static void main(String[] args) { 43 | 44 | int [][] arr={ {1,2},{3,4} }; 45 | 46 | matrixReshape(arr,1,4); 47 | // System.out.println(Arrays.deepToString(arr)); 48 | 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/SearchInsertPosition.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /*** 4 | * 5 | * 题目描述:给定一个有序不重复的数组,查找里面是否包含数字targe,如果有则返回其下标index, 6 | * 如果没有,则返回其应该插入的位置。 7 | * 8 | * 两种思路: 9 | * 10 | * (1)二分法O(logN),效率最高,尤其是在大数据量的体积下 11 | * 12 | * (2)线性扫描,O(N),大数量下可能并不高效 13 | * 14 | * 15 | */ 16 | public class SearchInsertPosition { 17 | public static int searchInsert(int[] nums, int target) { 18 | int start=0; 19 | int end=nums.length-1; 20 | 21 | while (start<=end){ 22 | int mid=start+(end-start)/2;//没有使用(start+end)/ 2 是为了防止数组越界 23 | int midVal=nums[mid]; 24 | if(midValtarget){ 27 | end=mid-1; 28 | }else { 29 | return mid; 30 | } 31 | 32 | } 33 | 34 | return start; 35 | } 36 | 37 | 38 | public static int searchInsert2(int[] nums, int target){ 39 | for (int i = 0; i < nums.length; i++) { 40 | if (nums[i] >= target) 41 | return i; 42 | } 43 | return nums.length; 44 | 45 | } 46 | 47 | 48 | 49 | public static void main(String[] args) { 50 | int arr[]={1,3,5,6}; 51 | 52 | System.out.println(searchInsert(arr,-1)); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/SelfDividingNumbers.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /**** 7 | * 8 | * https://leetcode.com/problems/self-dividing-numbers/ 9 | * 10 | * Self Dividing Numbers 11 | * 12 | * 给定一个数字范围,left和right,遍历其中的每一个数字 13 | * 14 | * 比如这个数字是123,那么这个数字本身,如果能除尽1,2,3,那么该数字就符合规则, 15 | * 如果数字里面包括0,就结束。 16 | * 17 | */ 18 | public class SelfDividingNumbers { 19 | 20 | public static List selfDividingNumbers(int left, int right) { 21 | List list=new ArrayList<>(); 22 | for (int i = left; i <=right ; i++) { 23 | if(isGood(i)){ 24 | list.add(i); 25 | } 26 | } 27 | return list; 28 | } 29 | 30 | 31 | private static boolean isGood(int temp){ 32 | int x=temp; 33 | 34 | while (x!=0){ 35 | int n=x%10;//取出数字的每一位 36 | //判断如果这位数字等于0,或者除不尽就直接返回false 37 | if(n==0|| temp%n != 0){ 38 | return false; 39 | } 40 | //继续向下除10 41 | x=x/10; 42 | } 43 | //如果x==0就返回true 44 | return true; 45 | 46 | } 47 | 48 | 49 | 50 | public static void main(String[] args) { 51 | 52 | selfDividingNumbers(1,22); 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/SortArrayByParity.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.Arrays; 4 | 5 | /*** 6 | *https://leetcode.com/problems/sort-array-by-parity/ 7 | */ 8 | public class SortArrayByParity { 9 | 10 | 11 | public static int[] sortArrayByParity(int[] A) { 12 | int start=0; 13 | int end=A.length-1; 14 | 15 | while (start=A.length||even>=A.length){ 28 | break; 29 | } 30 | 31 | int temp=A[even]; 32 | A[even]=A[odd]; 33 | A[odd]=temp; 34 | 35 | } 36 | 37 | 38 | 39 | return A; 40 | } 41 | 42 | public static void main(String[] args) { 43 | int a[]={4,2,5,7}; 44 | 45 | System.out.println(Arrays.toString(a)); 46 | sortArrayByParity(a); 47 | 48 | System.out.println(Arrays.toString(a)); 49 | 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/SortSpecialRange.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | /** 4 | * Created by qindongliang on 2018/8/5. 5 | */ 6 | public class SortSpecialRange { 7 | 8 | 9 | public static void main(String[] args) { 10 | 11 | //已知数组,假设最大值在[-100,100]之间 12 | int []nums={1,90,3,56,8,20,100}; 13 | 14 | //申请一个大于原数组一倍大小的数组空间,默认初始值都是0 15 | int []map=new int[201]; 16 | 17 | //将映射位置0标记为1,循环完毕,代表已经排序完 18 | for(int i=0;i= 0; p--) { 24 | if (Math.abs(A[i]) > Math.abs(A[j])) { 25 | result[p] = A[i] * A[i]; 26 | i++; 27 | } else { 28 | result[p] = A[j] * A[j]; 29 | j--; 30 | } 31 | } 32 | return result; 33 | } 34 | 35 | public static void main(String[] args) { 36 | 37 | System.out.println(Arrays.toString(sortedSquares( new int[]{-4,-1,0,3,10}))); 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/array_all/TransposeMatrix.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.array_all; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by qindongliang on 2018/8/12. 7 | */ 8 | public class TransposeMatrix { 9 | 10 | 11 | public static void main(String[] args) { 12 | 13 | 14 | // int [][]data={ {1,2,3},{4,5,6},{7,8,9} }; 15 | int [][]A={ {1,2,3},{4,5,6} }; 16 | 17 | 18 | int rows=A.length; 19 | int cols=A[0].length; 20 | 21 | int data2[][]=new int[cols][rows]; 22 | 23 | for (int i = 0; i map=new HashMap<>(); 25 | 26 | for (int i = 0; i 0&&A[j-1]>A[j]){ 28 | j--; 29 | } 30 | //判断是否相遇,并且i和j不能是原地(保证了长度肯定大于3) 31 | return i>0&&i==j&&j 1807 和 7810 8 | * 9 | * 让求出公牛的数字=所有猜正确的数字。 10 | * 11 | * 母牛的数字=猜错位置的计数 12 | * 13 | * 14 | */ 15 | public class BullsAndCows { 16 | 17 | public static String getHint(String secret, String guess) { 18 | 19 | int len = secret.length(); 20 | int []secretarr=new int[10]; 21 | int []guessarr=new int[10]; 22 | 23 | int bull=0; 24 | int cow=0; 25 | for (int i = 0; i < len; i++) { 26 | if(secret.charAt(i)==guess.charAt(i)){ 27 | bull++; 28 | }else{ 29 | secretarr[secret.charAt(i)-'0']++; 30 | guessarr[guess.charAt(i)-'0']++; 31 | } 32 | } 33 | 34 | 35 | System.out.println(); 36 | 37 | for (int i = 0; i < 10; i++) { 38 | cow=cow+Math.min(secretarr[i],guessarr[i]); 39 | } 40 | return ""+bull+"A"+cow+"B"; 41 | } 42 | 43 | 44 | public static void main(String[] args) { 45 | 46 | String s1="1123"; 47 | String s2="0111"; 48 | 49 | System.out.println(getHint(s1,s2)); 50 | 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/CountPrimes.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /**** 4 | * 5 | * https://leetcode.com/problems/count-primes/ 6 | * 7 | * 给定一个数字n,求在n之内这个范围内素数的个数 8 | * 9 | */ 10 | public class CountPrimes { 11 | 12 | public int countPrimes(int n) { 13 | boolean[] notPrime = new boolean[n]; 14 | int count = 0; 15 | for (int i = 2; i < n; i++) { 16 | //统计素数的的个数 17 | if (notPrime[i] == false) { 18 | count++; 19 | //把合数置为true 20 | for (int j = 2; i*j < n; j++) { 21 | notPrime[i*j] = true; 22 | } 23 | } 24 | } 25 | 26 | return count; 27 | } 28 | 29 | public static void main(String[] args) { 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/DailyTemperatures.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.Stack; 4 | 5 | /**** 6 | * 7 | * 8 | *https://leetcode.com/problems/daily-temperatures/ 9 | * 10 | * 给定一个代表温度的数组,现在让求出数组里面的每一天的温度,距离下一次温暖的天的中间间隔是多少。 11 | * 12 | * 思路:采用栈来保存,每一天的数据,然后取最新的与前面的每一个一次比较,求出距离,并设置。 13 | */ 14 | 15 | public class DailyTemperatures { 16 | 17 | public int[] dailyTemperatures(int[] T) { 18 | 19 | Stack stack=new Stack<>(); 20 | int []ret=new int[T.length];//初始化结果数组 21 | for (int i = 0; i < T.length; i++) { 22 | //栈里面必须有数据且最新的这个值要大于历史上最大的那个 23 | while (!stack.isEmpty()&&T[i]>T[stack.peek()]){ 24 | //取出这条数据 25 | int idx=stack.pop(); 26 | //设置该位置上的计算的距离最高温度的天数是多少 27 | ret[idx]=i-idx; 28 | } 29 | //入栈 30 | stack.push(i); 31 | } 32 | //返回结果集 33 | return ret; 34 | 35 | } 36 | 37 | public static void main(String[] args) { 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/DistributeCandies.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /**** 7 | * 8 | * https://leetcode.com/problems/distribute-candies/ 9 | * 10 | * 给定一个偶数长度的数组,假设是一堆糖果,现在要求平均分配给弟弟和妹妹, 11 | * 每一个数组的数字代表一种糖果,现在要求求出弟弟能获得不同糖果的最大类型 12 | * 13 | */ 14 | public class DistributeCandies { 15 | 16 | public int distributeCandies(int[] candies) { 17 | 18 | int total = candies.length; 19 | Set kinds = new HashSet(); 20 | for (int i = 0; i < total; i++) { 21 | kinds.add(candies[i]); 22 | } 23 | if (kinds.size() > total / 2) { 24 | return total / 2; 25 | } else { 26 | return kinds.size(); 27 | } 28 | 29 | 30 | } 31 | 32 | public static void main(String[] args) { 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/EmployeeImportance.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Queue; 7 | 8 | /**** 9 | * 10 | * https://leetcode.com/problems/employee-importance/ 11 | * 12 | */ 13 | public class EmployeeImportance { 14 | 15 | 16 | public int getImportance(List employees, int id) { 17 | 18 | HashMap map = new HashMap(); 19 | for(int i = 0; i < employees.size(); i++) 20 | map.put(employees.get(i).id,employees.get(i)); 21 | int sum = 0; 22 | Queue q = new LinkedList(); 23 | q.offer(map.get(id)); 24 | while(!q.isEmpty()){ 25 | Employee cur = q.poll(); 26 | sum += cur.importance; 27 | for(int i = 0; i < cur.subordinates.size(); i++) 28 | q.offer(map.get(cur.subordinates.get(i))); 29 | } 30 | return sum; 31 | } 32 | 33 | 34 | 35 | 36 | 37 | // Employee info 38 | class Employee { 39 | // It's the unique id of each node; 40 | // unique id of this employee 41 | public int id; 42 | // the importance value of this employee 43 | public int importance; 44 | // the id of direct subordinates 45 | public List subordinates; 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/HappyNumber.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /**** 4 | * 5 | * 6 | * 题目描述:给定一个整数n,判断这个数字是否符合happy数字的特征 7 | * 8 | * happy数字的特征是,将这个数拆分之后,每一部分的平方和会等于一个数, 9 | * 然后对这个数再次进行分解,如果最终能到每一个数字的平方和等于1,那么该数字 10 | * 就是happy数字,当然也会出现死循环,我们需要对这种情况做判断容错 11 | * 12 | * 13 | * 思路:对于给定的数字,计算当前每一个数字的平方和和,如果值==1,就返回true, 14 | * 其他的情况要判断是否有死循环,有就结束 15 | * 16 | * 17 | */ 18 | public class HappyNumber { 19 | 20 | public boolean isHappy(int n) { 21 | 22 | 23 | int x=n; 24 | int y=n; 25 | while (x>1){ 26 | 27 | x=cal(x);//计算平方和 28 | if(x==1){//符合要求返回 29 | return true; 30 | } 31 | 32 | y=cal(cal(y));//计算下一个依赖路径 33 | 34 | if(x==y){//死循环退出 35 | return false; 36 | } 37 | 38 | } 39 | 40 | 41 | return true; 42 | 43 | 44 | } 45 | 46 | 47 | public int cal(int n){ 48 | int x=n; 49 | int s=0; 50 | while (x>0){ 51 | s=s+(x%10)*(x%10); 52 | x=x/10; 53 | } 54 | return s; 55 | } 56 | 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/InterSectionTwoArray.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | /**** 8 | * 9 | *https://leetcode.com/problems/intersection-of-two-arrays/ 10 | * 11 | * 给定两个数组,求交集 12 | */ 13 | public class InterSectionTwoArray { 14 | public int[] intersection(int[] nums1, int[] nums2) { 15 | 16 | Set numbers=new HashSet<>(); 17 | 18 | for (int n:nums1) numbers.add(n); 19 | 20 | int []res=new int[numbers.size()]; 21 | 22 | int cursor=0; 23 | for (int n:nums2){ 24 | //如果nums2包含同样的节点,返回true 25 | if(numbers.remove(n)){ 26 | res[cursor++]=n; 27 | } 28 | } 29 | return Arrays.copyOfRange(res,0,cursor); 30 | } 31 | 32 | 33 | public static void main(String[] args) { 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/IntersectionTwoArraysII.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.Arrays; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /*** 8 | * 9 | * 求两个数组的交集2 10 | * 11 | */ 12 | public class IntersectionTwoArraysII { 13 | 14 | public int[] intersect(int[] nums1, int[] nums2) { 15 | 16 | Map map=new HashMap<>(); 17 | int maxSize=Math.min(nums1.length,nums2.length); 18 | 19 | int []result=new int[maxSize]; 20 | int size=0; 21 | 22 | for(int i:nums1){ 23 | map.put(i,map.getOrDefault(i,0)+1); 24 | } 25 | 26 | for (int i:nums2){ 27 | if(map.getOrDefault(i,0)>0){ 28 | result[size++]=i; 29 | map.put(i,map.get(i)-1); 30 | } 31 | } 32 | 33 | return Arrays.copyOf(result,size); 34 | } 35 | 36 | public static void main(String[] args) { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/IslandPerimeter.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | public class IslandPerimeter { 4 | public int islandPerimeter(int[][] grid) { 5 | 6 | int m=grid.length; 7 | int n=grid[0].length; 8 | 9 | int count=0; 10 | 11 | int [][] dir={{0,1},{1,0},{-1,0},{0,-1}}; 12 | 13 | for (int i = 0; i < m; i++) { 14 | for (int j = 0; j < n; j++) { 15 | if(grid[i][j]==1){ 16 | for(int []d:dir){ 17 | int x=i+d[0]; 18 | int y=j+d[1]; 19 | 20 | if(x<0||y<0||x==m||y==n||grid[x][y]==0){ 21 | count++; 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | return count; 29 | 30 | } 31 | 32 | 33 | 34 | public static void main(String[] args) { 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/IsomorphicStrings.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /**** 4 | * 5 | * 6 | * 链接:https://leetcode.com/problems/isomorphic-strings/ 7 | * 同构词 8 | * 9 | * 给定两个字符s和t,然后判断这两个词是否是同构词, 10 | * 11 | * 比如egg和add,paper和title就可以。但foo和bar就不行 12 | * 13 | * 14 | * 15 | */ 16 | public class IsomorphicStrings { 17 | 18 | public static boolean isIsomorphic(String s, String t) { 19 | 20 | //256代表所有的ascii码的可能 21 | int []m1=new int[256]; 22 | int []m2=new int[256]; 23 | 24 | int n=s.length(); 25 | for (int i = 0; i < n; i++) { 26 | //判断相同的位置是否不相等,如果不相等则返回false 27 | if(m1[s.charAt(i)]!=m2[t.charAt(i)]){ 28 | return false; 29 | } 30 | //相等则都从0计数,保持统一 31 | m1[s.charAt(i)]=i+1; 32 | m2[t.charAt(i)]=i+1; 33 | } 34 | 35 | //若都符合,都返回true 36 | return true; 37 | 38 | 39 | } 40 | 41 | public static void main(String[] args) { 42 | 43 | System.out.println(isIsomorphic("egg","add")); 44 | 45 | 46 | } 47 | 48 | 49 | 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/JewelsandStones.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /*** 4 | * 5 | * https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html 6 | * 7 | * 8 | */ 9 | public class JewelsandStones { 10 | 11 | public static int numJewelsInStones(String J, String S) { 12 | String text = S.replaceAll("[^" + J + "]", ""); 13 | // System.out.println(text); 14 | 15 | return text.length(); 16 | } 17 | 18 | 19 | public static int numJewelsInStones2(String J, String S) { 20 | int[] a = new int[58]; //小写+大写共有58个字符 21 | for (char stone : J.toCharArray()) { 22 | a[stone - 65]++; 23 | } 24 | int sum = 0; 25 | for (char jewel : S.toCharArray()) 26 | sum += a[jewel - 65]; 27 | 28 | return sum; 29 | } 30 | 31 | 32 | public static void main(String[] args) { 33 | 34 | //替换除了J里面的所有字符,在S里面其他的都为空 35 | numJewelsInStones("aA", "aAAbbbb"); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/MyHashMap.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /**** 4 | * 5 | * https://leetcode.com/problems/design-hashmap/discuss/270685/Java-Separate-Chaining-with-rehashing 6 | * 7 | * Design HashMap 8 | * 9 | * 10 | */ 11 | public class MyHashMap { 12 | 13 | Object []store; 14 | 15 | /** Initialize your data structure here. */ 16 | public MyHashMap() { 17 | store=new Object[1000001]; 18 | } 19 | 20 | /** value will always be non-negative. */ 21 | public void put(int key, int value) { 22 | store[key]=value; 23 | } 24 | 25 | /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */ 26 | public int get(int key) { 27 | if(store[key]!=null){ 28 | return (Integer) store[key]; 29 | }else{ 30 | return -1; 31 | } 32 | } 33 | 34 | /** Removes the mapping of the specified value key if this map contains a mapping for the key */ 35 | public void remove(int key) { 36 | if(store[key]!=null){ 37 | store[key]=-1; 38 | } 39 | } 40 | 41 | 42 | public static void main(String[] args) { 43 | 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/MyHashSet.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.Arrays; 4 | 5 | /**** 6 | * 7 | * https://leetcode.com/problems/design-hashset/ 8 | * 9 | * 实现一个hashset结构 10 | * 11 | * 12 | */ 13 | public class MyHashSet { 14 | 15 | boolean []arr=new boolean[100]; 16 | 17 | /** Initialize your data structure here. */ 18 | public MyHashSet() { 19 | 20 | } 21 | 22 | public void add(int key) { 23 | 24 | if(key>=arr.length){ 25 | extend(key); 26 | } 27 | arr[key]=true; 28 | 29 | } 30 | 31 | public void remove(int key) { 32 | if(key=arr.length){ 40 | return false; 41 | } 42 | 43 | return arr[key]; 44 | } 45 | 46 | 47 | public void extend(int key){ 48 | arr= Arrays.copyOf(arr,key+2); 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/NumberofBoomerangs.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class NumberofBoomerangs { 7 | 8 | 9 | public int numberOfBoomerangs(int[][] points) { 10 | 11 | int count=0; 12 | Map map=new HashMap<>(points.length); 13 | for(int []i :points){ 14 | for (int []j:points){ 15 | int dx=i[0]-j[0]; 16 | int dy=i[1]-j[1]; 17 | int d=dx*dx+dy*dy; 18 | Integer v=map.get(d); 19 | if(v!=null){ 20 | count+=2*v; 21 | map.put(d,v+1); 22 | }else{ 23 | map.put(d,1); 24 | } 25 | } 26 | map.clear(); 27 | } 28 | 29 | 30 | return count; 31 | } 32 | 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/OccurrencesAfterBigram.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /*** 8 | * 9 | * https://leetcode.com/problems/occurrences-after-bigram/ 10 | * 11 | * 给出第1个和第二个单词,让求出第三个单词,并返回结果数组 12 | */ 13 | public class OccurrencesAfterBigram { 14 | 15 | public static String[] findOcurrences(String text, String first, String second) { 16 | List res = new ArrayList<>(); 17 | String words[] = text.split(" "); 18 | for (int i = 0; i < words.length - 2; i++) { 19 | if (words[i].equals(first) && words[i + 1].equals(second)) { 20 | res.add(words[i + 2]); 21 | } 22 | 23 | } 24 | return res.toArray(new String[2]); 25 | } 26 | 27 | public static void main(String[] args) { 28 | 29 | String[] arr = findOcurrences("alice is a good girl she is a good student", "a", "good"); 30 | 31 | System.out.println(Arrays.toString(arr)); 32 | 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/PowerfulInteger.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /***** 9 | * 10 | * 链接:https://leetcode.com/problems/powerful-integers/ 11 | * 12 | * 给定两个整形数字x和y,并给出一个限定范围, 13 | * 现在让求出所有x^i + y^j的值,并且这个值小于等于我们设置的bound值 14 | * 15 | * 16 | */ 17 | public class PowerfulInteger { 18 | 19 | public static List powerfulIntegers(int x, int y, int bound) { 20 | //集合存储结果 21 | Set seen=new HashSet<>(); 22 | //使用类似笛卡尔的积的方式来双层遍历 23 | for (int i = 1; i <=bound ; i=i*x) { 24 | for (int j = 1; i+j <= bound; j=j*y) { 25 | seen.add(i+j);//存储计算后的结构 26 | if(y==1){ 27 | break;//做一层优化,提前退出 28 | } 29 | } 30 | 31 | if(x==1) break;//做一层优化,提前退出 32 | } 33 | //将最终的结果以list方法返回 34 | return new ArrayList<>(seen); 35 | } 36 | 37 | 38 | public static void main(String[] args) { 39 | 40 | System.out.println(powerfulIntegers(2,3,10)); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/ShortestCompletingWord.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | /**** 4 | * 5 | * 给定一个单词s,让求出words数组里面,最短的那个word与s里面的字母重合 6 | * 7 | */ 8 | public class ShortestCompletingWord { 9 | 10 | public String shortestCompletingWord(String s, String[] words) { 11 | 12 | int []counts=new int[26]; 13 | 14 | int total=0; 15 | //对字符串里面出现的字母进行计数 16 | for (char c:s.toLowerCase().toCharArray()){ 17 | if('a'<=c&&c<='z'){ 18 | counts[c-'a']++; 19 | total++; 20 | } 21 | } 22 | 23 | String res=null; 24 | //遍历数组里面每一个word进行判断 25 | for (String w:words){ 26 | int n=total; 27 | int []cnts=counts.clone(); 28 | //如果某个计数值大于0就递减 29 | for (char c:w.toCharArray()){ 30 | if(cnts[c-'a']-->0){ 31 | n--;//总数也递减 32 | } 33 | } 34 | 35 | //如果n=0,说明这个单词里面的单词和要找到的单词由重合,符合我们的要找的规律, 36 | //同时,如果后面出现多个这样规律的单词时,我们取长度短的作为返回值 37 | if(n==0&&(res==null||w.length()= A.length / 2) { 36 | return i; 37 | } 38 | } 39 | return 0; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/SubdomainVisitCount.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /**** 9 | * 10 | * 统计域名出现的次数 11 | * 12 | */ 13 | public class SubdomainVisitCount { 14 | 15 | public List subdomainVisits(String[] cpdomains) { 16 | 17 | Map map = new HashMap(); 18 | 19 | for (String cd:cpdomains){ 20 | 21 | int i=cd.indexOf(' '); 22 | int n=Integer.valueOf(cd.substring(0,i)); 23 | String s=cd.substring(i+1); 24 | 25 | for(i=0;i res=new ArrayList<>(); 38 | for(String d:map.keySet()){ 39 | res.add(map.get(d)+" "+d); 40 | } 41 | 42 | return res; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/UncommonWordTwoSentences.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.*; 4 | 5 | /**** 6 | * 7 | * https://leetcode.com/problems/uncommon-words-from-two-sentences/ 8 | * 9 | * 题目描述:给出两个句子,求出在这两个句子里面仅仅出现一次word 10 | * 11 | */ 12 | public class UncommonWordTwoSentences { 13 | 14 | public static String[] uncommonFromSentences(String A, String B) { 15 | 16 | 17 | String all=A+" "+B; 18 | HashMap map=new HashMap<>(); 19 | for(String word:all.split(" ")){ 20 | map.put(word,map.getOrDefault(word,0)+1); 21 | } 22 | List result=new ArrayList<>(); 23 | for (Map.Entry kv:map.entrySet()){ 24 | if(kv.getValue()==1){ 25 | result.add(kv.getKey()); 26 | } 27 | } 28 | // System.out.println(result); 29 | return result.toArray(new String[0]); 30 | } 31 | 32 | public static void main(String[] args) { 33 | 34 | String A = "this apple is sweet", B = "this apple is sour"; 35 | 36 | uncommonFromSentences(A,B); 37 | 38 | 39 | } 40 | 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/ValidAnagram.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | public class ValidAnagram { 4 | 5 | public static boolean isAnagram(String s, String t) { 6 | 7 | char arr1[]=s.toCharArray(); 8 | char arr2[]=t.toCharArray(); 9 | if(arr1.length!=arr2.length){ 10 | return false; 11 | } 12 | int ct[]=new int[26]; 13 | 14 | for (int i = 0; i < arr1.length; i++) { 15 | ct[arr1[i]-'a']++; 16 | ct[arr2[i]-'a']--; 17 | } 18 | 19 | for (int i : ct) { 20 | if(i!=0) return false; 21 | } 22 | 23 | return true; 24 | } 25 | 26 | public static void main(String[] args) { 27 | 28 | System.out.println(isAnagram("abe","bca")); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/hash_table_all/WordPattern.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.hash_table_all; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /***** 7 | * 8 | * 9 | * https://leetcode.com/problems/word-pattern/ 10 | * 11 | * 题目描述:给定一个p和t,p和t之间存在之间的模式的映射关闭 12 | * 13 | * 如 abba 和 dog cat cat dog存在相同的关系,如下: 14 | * 15 | * a b b a 16 | * dog cat cat dog 17 | * 符合对称映射,如abba和dog dog dog dog就构不成这种关系。 18 | * 19 | * 思路:采用hashmap来解决 20 | * 21 | * 如果两个字符串里面符合对称模式,那么他们在map里面出现的映射顺序,其实是相似的。 22 | * 23 | * 24 | * 25 | * 26 | */ 27 | public class WordPattern { 28 | 29 | public boolean wordPattern(String pattern, String str) { 30 | //转成数组 31 | String[] words = str.split(" "); 32 | //必须长度相等,才有机会构成映射 33 | if (words.length != pattern.length()) 34 | return false; 35 | Map index = new HashMap(); 36 | //放pattern里面的每一个字符到map里,同时放str里面的每一个单词也到map里 37 | //如果他们的映射是对称的,那么两者必定符合同时出现的规律,一旦有一个不符合就说明映射失败 38 | for (Integer i=0; i 0; N /= 2, d++) 28 | if (N % 2 == 1) { 29 | res = Math.max(res, d); 30 | d = 0; 31 | } 32 | return res; 33 | } 34 | 35 | public static void main(String[] args) { 36 | 37 | 38 | System.out.println(binaryGap(22)); 39 | 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/math/ComplementBaseInteger.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math; 2 | 3 | /**** 4 | *https://leetcode.com/problems/complement-of-base-10-integer/ 5 | * 6 | * 待排查 7 | * 8 | * 9 | * 10 | */ 11 | public class ComplementBaseInteger { 12 | 13 | public int bitwiseComplement(int N) { 14 | int X = 1; 15 | while (N > X) X = X * 2 + 1; 16 | return X - N; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/math/DIStringMatch.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math; 2 | 3 | /**** 4 | * 5 | * 链接:https://leetcode.com/problems/di-string-match/ 6 | * 7 | * 给定一个字符串,里面仅仅包含两个字母I和D,现在让返回整个集合任何相关的变形 8 | * 9 | * If S[i] == "I", then A[i] < A[i+1] 10 | * If S[i] == "D", then A[i] > A[i+1] 11 | * 12 | * 如: 13 | * Input: "IDID" 14 | * Output: [0,4,1,3,2] 15 | * 16 | * 思路: 17 | * 18 | * 使用数组的双指针法,对于遇到I的,进行从左到右赋值,否则则从右向左赋值,依次遍历结束 19 | * 数组的最后一位,等于最左边的left的偏移量值 20 | * 21 | * 22 | */ 23 | public class DIStringMatch { 24 | 25 | public int[] diStringMatch(String S) { 26 | 27 | int n=S.length(); 28 | int left=0; 29 | int right=n; 30 | int []res=new int[n+1]; 31 | for (int i = 0; i < n; i++) { 32 | res[i]=S.charAt(i)=='I'?left++:right--; 33 | } 34 | 35 | res[n]=left; 36 | 37 | return res; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/math/DistributeCandiesToPeople.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math; 2 | 3 | import java.util.Arrays; 4 | 5 | /**** 6 | * 7 | * 8 | *https://leetcode.com/problems/distribute-candies-to-people/ 9 | * 10 | * 分糖果,拿着指定数量的糖果,分给n个人,第一个人分1个,第二个人分2个,第n个人分n个 11 | * 依次类推,直到把所有的糖果分完,求出每个人分糖果的数量。 12 | * 13 | */ 14 | public class DistributeCandiesToPeople { 15 | 16 | 17 | public static int[] distributeCandies(int candies, int num_people) { 18 | 19 | int res[]=new int[num_people]; 20 | 21 | for (int i = 0; candies>0 ; i++) { 22 | res[i%num_people]+=Math.min(candies,i+1); 23 | candies=candies-(i+1); 24 | } 25 | 26 | return res; 27 | } 28 | 29 | public static void main(String[] args) { 30 | 31 | 32 | System.out.println(Arrays.toString(distributeCandies(10,3))); 33 | 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/math/DivisorGame.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math; 2 | 3 | /**** 4 | * 5 | * https://leetcode.com/problems/divisor-game/ 6 | * 7 | * 8 | * 两个人玩游戏,假设第一个人先开始, 9 | * 10 | * 最初有一个数字N写在黑板上,然后每个人一次选择一个数字x,范围在0= b >= c, a,b,c 可以得到一个三角形, 如果 a < b + c. 11 | * 12 | * 思路: 13 | * 14 | * 1,排序数组 15 | * 2,试着检查连续的三个数字能否组成一个三角形 16 | * 3,如果 A[n-1] < A[n-2] + A[n-3],我们可以得到一个三角形 17 | * 4,如果A[n-1] >= A[n-2] + A[n-3] ,这个不满足三角形的条件 18 | * 19 | */ 20 | public class LargestPerimeterTriangle { 21 | 22 | public int largestPerimeter(int[] A) { 23 | Arrays.sort(A); 24 | //倒序遍历计算 25 | for (int i = A.length-1; i >1 ; i--) { 26 | //A[i]一定是最大的 27 | if(A[i]0){ 22 | res++; 23 | } 24 | } 25 | 26 | res+=x+y; 27 | 28 | 29 | } 30 | 31 | 32 | return res; 33 | 34 | } 35 | 36 | 37 | public static void main(String[] args) { 38 | 39 | 40 | int [][]arr=new int[][]{{2}}; 41 | System.out.println(projectionArea(arr)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/math/SmallestRange.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.math; 2 | 3 | /*** 4 | * 5 | *https://leetcode.com/problems/smallest-range-i/ 6 | * 7 | * no 8 | * 9 | * If min(A) + K < max(A) - K, then return max(A) - min(A) - 2 * K 10 | * If min(A) + K >= max(A) - K, then return 0 11 | * 12 | */ 13 | public class SmallestRange { 14 | 15 | public int smallestRangeI(int[] A, int K) { 16 | 17 | int mx=A[0]; 18 | int mn=A[0]; 19 | for (int a:A){ 20 | mx=Math.max(mx,a); 21 | mn=Math.min(mn,a); 22 | } 23 | return Math.max(0,mx-mn-2*K); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/BuddyString.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /*** 9 | * https://leetcode.com/problems/buddy-strings/ 10 | * 11 | * 给定2个字符串,如果他们的两个字符可以交换位置,例如ab,ba那么他们就符合要求 12 | * 解决思路,首先两个字符串的长度一定得相等,否则直接返回false 13 | * 其次,如果两个字符串相等,我们需要判断都是同一个字母,还是不同的字母,只有是同一个字母 14 | * 组成的才能返回true,最后如果不相等,我们需要用一个集合把不相等的字符收集起来 15 | * 最后判断,其size必须等于2,然后他们对应的字符串中位置取出来的字符相比,必须相等 16 | * 这样就符合要求。 17 | */ 18 | 19 | public class BuddyString { 20 | 21 | public boolean buddyStrings(String A, String B) { 22 | 23 | if(A.length()!=B.length()) return false; 24 | if(A.equals(B)){ 25 | Set s=new HashSet<>(); 26 | for (char c : A.toCharArray()) s.add(c); 27 | return s.size() dif=new ArrayList<>(); 31 | 32 | for (int i = 0; i < A.length(); ++i) { 33 | if(A.charAt(i)!=B.charAt(i)) dif.add(i); 34 | } 35 | 36 | return dif.size()==2 && A.charAt(dif.get(0)) == B.charAt(dif.get(1)) && A.charAt(dif.get(1)) == B.charAt(dif.get(0)); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/CheckPalindrome2.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all; 2 | 3 | /***** 4 | * 回文数:正读倒读都一样的整数 5 | * 1234321 奇数回文数 6 | * 124421 偶数回文数 7 | */ 8 | public class CheckPalindrome2 { 9 | 10 | /*** 11 | * 使用双指针法判断是不是回文数字,然后最后在删除一位后判断 12 | * @param s 13 | * @return 14 | */ 15 | public static boolean validPalindrome(String s) { 16 | 17 | int start=0; 18 | int end=s.length()-1; 19 | while (start=end) return true; 24 | //删除一位后进行判断 25 | if(isPalin(s,start+1,end)||isPalin(s,start,end-1)) return true; 26 | return false; 27 | } 28 | 29 | private static boolean isPalin(String s , int i, int j){ 30 | while (i-1) return count; 25 | else return sb.append(A).toString().lastIndexOf(B) >-1 ? count+1:-1 ; 26 | } 27 | 28 | 29 | public static void main(String[] args) { 30 | System.out.println(repeatedStringMatch("abcd","cdabedab")); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/ReverseString2.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all; 2 | 3 | /*** 4 | * 5 | * https://leetcode.com/problems/reverse-string-ii/ 6 | * 每隔2k个数字之后,对前面的k个数字做反转,如果长度不够则不做处理。 7 | */ 8 | public class ReverseString2 { 9 | 10 | public static String reverseStr(String s, int k) { 11 | 12 | char []a=s.toCharArray(); 13 | 14 | for (int start = 0; start ("01", "0011", "000111") 15 | */ 16 | public class CountBinarySubstring { 17 | 18 | public static int countBinarySubstrings(String s) { 19 | int cur = 1, pre = 0, res = 0; 20 | for (int i = 1; i < s.length(); i++) {//从1开始计算 21 | if (s.charAt(i) == s.charAt(i - 1)){ 22 | cur++;//如果和前一个相等,那么cur+1即可 23 | } else {//如果不相等,则和前一个去最小值 24 | res += Math.min(cur, pre);// 25 | pre = cur;//把cur赋值给上一次的值 26 | cur = 1;//当前继续从1开始 27 | } 28 | } 29 | //最后一次 30 | return res + Math.min(cur, pre); 31 | } 32 | 33 | public static void main(String[] args) { 34 | 35 | System.out.println(countBinarySubstrings("001")); 36 | // System.out.println(countBinarySubstrings("00110011")); 37 | 38 | 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/detect_capital/DetectCapital.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all.detect_capital; 2 | 3 | public class DetectCapital { 4 | 5 | public static boolean detectCapitalUse(String word) { 6 | 7 | int upperCount=0; 8 | int lowwerCount=0; 9 | char letters[]=word.toCharArray(); 10 | char firstLetter=letters[0]; 11 | 12 | for (int i = 0; i < letters.length ; i++) { 13 | char c=letters[i]; 14 | if(c>=65 && c<=90){ 15 | upperCount++; 16 | }else{ 17 | lowwerCount++; 18 | } 19 | } 20 | 21 | if(upperCount==letters.length||lowwerCount==letters.length){ 22 | return true; 23 | } 24 | 25 | 26 | 27 | if( upperCount==1 && (firstLetter>=65 && firstLetter<=90 )){ 28 | return true; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | 35 | 36 | 37 | public static void main(String[] args) { 38 | 39 | System.out.println(detectCapitalUse("Faaab")); 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/goat_latin/GoatLatin.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all.goat_latin; 2 | 3 | import java.util.*; 4 | 5 | public class GoatLatin { 6 | 7 | private static final Set vowels = new HashSet<>(Arrays.asList('a','e','i','o','u','A','E','I','O','U')); 8 | 9 | public static String toGoatLatin(String s){ 10 | 11 | StringBuilder sb=new StringBuilder(); 12 | String array[]=s.split(" "); 13 | for(int i=0;i unique=new HashSet<>(); 14 | for (String word:words){ 15 | StringBuilder sb=new StringBuilder(); 16 | for(char c : word.toCharArray()){ 17 | sb.append( morseCodes[c-'a']); 18 | } 19 | unique.add(sb.toString()); 20 | } 21 | return unique.size(); 22 | 23 | 24 | } 25 | 26 | public static void main(String[] args) { 27 | 28 | 29 | 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/string_all/reverse_word/ReverseWord1.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.string_all.reverse_word; 2 | 3 | /** 4 | * 字符串反转例子 5 | * 6 | * Created by qindongliang on 2018/12/22. 7 | */ 8 | public class ReverseWord1 { 9 | 10 | 11 | public static String reverseString(String s) { 12 | char orgin[]=s.toCharArray(); 13 | 14 | int len=orgin.length-1; 15 | int start=0; 16 | 17 | 18 | while(start map=new HashMap<>(); 13 | static { 14 | map.put('I',1); 15 | map.put('V',5); 16 | map.put('X',10); 17 | map.put('L',50); 18 | map.put('C',100); 19 | map.put('D',500); 20 | map.put('M',1000); 21 | } 22 | 23 | public static int romanToInt(String s) { 24 | char romans[]=s.toCharArray(); 25 | int sum=0; 26 | 27 | for (int i = 0; i < romans.length-1; i++) { 28 | 29 | int cur=map.get(romans[i]); 30 | int next=map.get(romans[i+1]); 31 | 32 | if(cur='A'&&c<='Z'){ 15 | c= (char) (c+ 32); 16 | } 17 | sb.append(c); 18 | 19 | } 20 | return sb.toString(); 21 | } 22 | 23 | 24 | public static void test1(){ 25 | 26 | for (int i='a';i<='z';i++){ 27 | 28 | System.out.print(i+""+ (char)i+" "); 29 | 30 | } 31 | System.out.println(); 32 | for (int i='A';i<='Z';i++){ 33 | 34 | System.out.print(i+""+ (char)i+" "); 35 | 36 | } 37 | 38 | 39 | } 40 | 41 | 42 | public static void main(String[] args) { 43 | test1(); 44 | System.out.println(toLowerCase("CaseZADFDC")); 45 | } 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/AverageLevelTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Queue; 7 | 8 | /*** 9 | * 10 | * 题目描述:给定一个二叉树,让求出每层的节点的平均值,最后以一个list返回 11 | * 12 | * 思路:其实是考察二叉树的的层级遍历的知识点,迭代的方式非常简洁如下。 13 | * 14 | */ 15 | public class AverageLevelTree { 16 | 17 | public List averageOfLevels(TreeNode root) { 18 | List result=new ArrayList<>(); 19 | if(root==null) return result; 20 | 21 | Queue queue=new LinkedList<>(); 22 | queue.add(root); 23 | 24 | while (!queue.isEmpty()){ 25 | int size=queue.size(); 26 | double sum=0.0; 27 | for (int i = 0; i < size; i++) { 28 | TreeNode node=queue.poll(); 29 | sum+=node.val; 30 | if(node.left!=null) queue.add(node.left); 31 | if(node.right!=null) queue.add(node.right); 32 | } 33 | result.add(sum*1.0/size); 34 | } 35 | 36 | return result; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/BinaryTreeTilt.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | public class BinaryTreeTilt { 4 | 5 | int result = 0; 6 | 7 | public int findTilt(TreeNode root) { 8 | postOrder(root); 9 | return result; 10 | } 11 | 12 | private int postOrder(TreeNode root) { 13 | if (root == null) return 0; 14 | int left = postOrder(root.left); 15 | int right = postOrder(root.right); 16 | result += Math.abs(left - right); 17 | return left + right + root.val; 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/CheckBalancedBinaryTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | /**** 4 | * 5 | * https://leetcode.com/problems/balanced-binary-tree/ 6 | * 7 | * 题目描述:检查一棵树是否为平衡的二叉树 8 | * 9 | * 10 | */ 11 | public class CheckBalancedBinaryTree { 12 | 13 | boolean isBalanced = true; 14 | 15 | public boolean isBalanced(TreeNode root) { 16 | 17 | if (root == null) return isBalanced; 18 | 19 | backTrack(root); 20 | return isBalanced; 21 | } 22 | 23 | public int backTrack(TreeNode node) { 24 | 25 | if (node == null) { 26 | return 0; 27 | } 28 | //求左子树高度 29 | int left = backTrack(node.left); 30 | //求右子树的高度 31 | int right = backTrack(node.right); 32 | //如果他们的绝对值大于1,就说明不均衡 33 | if (Math.abs(left - right) > 1) { 34 | isBalanced = false; 35 | } 36 | //如果符合均衡,就返回这个子树最大的高度,继续回溯判断 37 | return Math.max(left, right) + 1; 38 | } 39 | 40 | 41 | public static void main(String[] args) { 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/LeafSimilar.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | import leetcode.easy.tree_all.TreeNode; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by qindongliang on 2018/11/18. 10 | */ 11 | public class LeafSimilar { 12 | 13 | 14 | public static boolean leafSimilar(TreeNode root1,TreeNode root2){ 15 | //比较两颗子树的叶子节点是否相似 16 | List list1=new ArrayList<>(); 17 | List list2=new ArrayList<>(); 18 | 19 | dfs(root1,list1); 20 | dfs(root2,list2); 21 | 22 | return list1.equals(list2); 23 | } 24 | 25 | public static void dfs(TreeNode n,List list){ 26 | if(n==null) return; 27 | if(n.left==null&&n.right==null){ 28 | list.add(n.val);//叶子节点 29 | } 30 | dfs(n.left,list);//左边递归 31 | dfs(n.right,list);//右边递归 32 | 33 | } 34 | 35 | 36 | public static void main(String[] args) { 37 | leafSimilar(TreeNode.getRoot(),TreeNode.getRoot()); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/LowestCommonAncestor.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | /**** 4 | * 5 | * link: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/ 6 | * 7 | * 给定两个节点,让求出这两个节点的最小公共父节点的值 8 | * 9 | */ 10 | public class LowestCommonAncestor { 11 | 12 | public static void main(String[] args) { 13 | 14 | } 15 | 16 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 17 | 18 | if(root.val>p.val&&root.val>q.val){ 19 | return lowestCommonAncestor(root.left,p,q); 20 | }else if(root.valp.val&&root.val>q.val){ 35 | root=root.left; 36 | }else if(root.val children; 11 | 12 | public Node() {} 13 | 14 | public Node(int _val, List _children) { 15 | val = _val; 16 | children = _children; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/PathInLabledBinaryTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | /**** 7 | * 8 | * 链接:https://leetcode.com/problems/path-in-zigzag-labelled-binary-tree/ 9 | * 描述:给定一颗完全二叉树,并给定一个lable值,让求出从root开始,到这个lable值的路径列表 10 | * 11 | * 解决方法:借助完全二叉树的性质,来解答该题 12 | * 13 | * 14 | */ 15 | 16 | public class PathInLabledBinaryTree { 17 | 18 | public static void main(String[] args) { 19 | 20 | } 21 | 22 | //如题描述,该树是一颗完全二叉树 23 | public List pathInZigZagTree(int label) { 24 | 25 | LinkedList result = new LinkedList<>(); 26 | int parent = label; 27 | result.addFirst(parent); 28 | 29 | while (parent != 1) { 30 | //利用对数换底公式求得,log2N的值,也就是parent在的层级, 31 | int depth = (int) (Math.log(parent) / Math.log(2)); 32 | //2的n次方-1代表整个二叉树节点的个数,再减去parent代表parent节点所处的位置 33 | int offset = (int) Math.pow(2, depth + 1) - 1 - parent; 34 | //获取父节点的值 35 | parent = (int) (Math.pow(2, depth) + offset) / 2; 36 | //总是插入链表的头部 37 | result.addFirst(parent); 38 | } 39 | 40 | return result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/PathSumIII.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | /*** 4 | * https://leetcode.com/problems/path-sum-iii/ 5 | */ 6 | public class PathSumIII { 7 | 8 | 9 | int result = 0; 10 | 11 | public int pathSum(TreeNode root, int sum) { 12 | if (root == null) return 0; 13 | helper(root, sum); 14 | pathSum(root.left, sum); 15 | pathSum(root.right, sum); 16 | return result; 17 | } 18 | 19 | public void helper(TreeNode root, int sum) { 20 | if (root == null) return; 21 | if (sum - root.val == 0) result += 1; 22 | helper(root.left, sum - root.val); 23 | helper(root.right, sum - root.val); 24 | } 25 | 26 | 27 | public static void main(String[] args) { 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/RangeSumBST.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | /**** 4 | * 5 | * 题目连接:https://leetcode.com/problems/range-sum-of-bst/ 6 | * 给定一个二叉搜索树,然后求节点值范围在指定的[L-R]之间的所有数值的和。 7 | * 思路: 8 | * 9 | * rangeSumBST2方法是我自己想出来的,效率比较低,整个树都得遍历依次, 10 | * rangeSumBST方法这个效率比较,每次减少遍历判断次数 11 | * 12 | */ 13 | public class RangeSumBST { 14 | int sum=0; 15 | public int rangeSumBST2(TreeNode root, int L, int R) { 16 | 17 | if(root==null) return 0; 18 | if(root.val>=L&&root.val<=R){ 19 | sum+=root.val; 20 | } 21 | rangeSumBST(root.left,L,R); 22 | rangeSumBST(root.right,L,R); 23 | return sum; 24 | } 25 | 26 | 27 | 28 | 29 | 30 | 31 | public int rangeSumBST(TreeNode root, int L, int R) { 32 | if(root == null) return 0; 33 | if(root.val > R) return rangeSumBST(root.left, L, R); 34 | if(root.val < L) return rangeSumBST(root.right, L, R); 35 | return root.val + rangeSumBST(root.left, L, R) + rangeSumBST(root.right, L, R); 36 | } 37 | 38 | public static void main(String[] args) { 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/SameTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | /**** 7 | * 8 | * 题目连接:https://leetcode.com/problems/same-tree/ 9 | * 描述:给定二个二叉树,让判断二颗树的值是否完全相等。 10 | * 11 | * 12 | */ 13 | public class SameTree { 14 | 15 | public boolean isSameTree2(TreeNode p, TreeNode q) { 16 | 17 | if (p == null || q == null) { 18 | return p == q; 19 | } 20 | if (p.val == q.val) { 21 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 22 | } 23 | 24 | return false; 25 | 26 | } 27 | 28 | 29 | public boolean isSameTree(TreeNode p, TreeNode q) { 30 | Queue queue = new LinkedList<>(); 31 | queue.add(p); 32 | queue.add(q); 33 | while (!queue.isEmpty()) { 34 | TreeNode f = queue.poll(); 35 | TreeNode s = queue.poll(); 36 | if (f == null && s == null) { 37 | continue; 38 | } else if (f == null || s == null || f.val != s.val) { 39 | return false; 40 | } 41 | queue.add(f.left); 42 | queue.add(s.left); 43 | queue.add(f.right); 44 | queue.add(s.right); 45 | } 46 | 47 | return true; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/SecondMinimumNode.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | /*** 4 | * 5 | * https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/ 6 | * 7 | * 8 | * 9 | * 10 | */ 11 | public class SecondMinimumNode { 12 | 13 | public static void main(String[] args) { 14 | 15 | } 16 | 17 | public int findSecondMinimumValue(TreeNode root) { 18 | 19 | if (root.left == null) return -1; 20 | 21 | int l = root.left.val == root.val ? findSecondMinimumValue(root.left) : root.left.val; 22 | int r = root.right.val == root.val ? findSecondMinimumValue(root.right) : root.right.val; 23 | 24 | return l == -1 || r == -1 ? Math.max(l, r) : Math.min(l, r); 25 | 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/TreeNode.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | public class TreeNode { 4 | 5 | public int val; 6 | public TreeNode left; 7 | public TreeNode right; 8 | public TreeNode(int x) { val = x; } 9 | 10 | 11 | public static TreeNode getRoot(){ 12 | // https://leetcode.com/problems/leaf-similar-trees/ 13 | 14 | 15 | TreeNode node3=new TreeNode(3); 16 | TreeNode node5=new TreeNode(5); 17 | TreeNode node1=new TreeNode(1); 18 | TreeNode node6=new TreeNode(6); 19 | TreeNode node2=new TreeNode(2); 20 | TreeNode node7=new TreeNode(7); 21 | TreeNode node4=new TreeNode(4); 22 | TreeNode node9=new TreeNode(9); 23 | TreeNode node8=new TreeNode(8); 24 | 25 | node3.left=node5; 26 | node3.right=node1; 27 | node5.left=node6; 28 | node5.right=node2; 29 | node2.left=node7; 30 | node2.right=node4; 31 | node1.left=node9; 32 | node1.right=node8; 33 | 34 | 35 | return node3; 36 | } 37 | 38 | 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/leetcode/easy/tree_all/UnivaluedBinaryTree.java: -------------------------------------------------------------------------------- 1 | package leetcode.easy.tree_all; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | /***** 7 | * 8 | * 题目连接:https://leetcode.com/problems/univalued-binary-tree/ 9 | * 10 | * 给定一个二叉树让判断整个树的节点值是不是都是相等的,如果相等就返回true,否则就返回false 11 | * 12 | * 思路: 13 | * 下面使用了两种方法: 14 | * 15 | * (1)第一种是迭代的方式 16 | * 17 | * (2)第二种是递归的方式 18 | * 19 | * 20 | */ 21 | public class UnivaluedBinaryTree { 22 | 23 | public boolean isUnivalTree(TreeNode root) { 24 | 25 | Queue q=new LinkedList<>(); 26 | q.add(root); 27 | while (!q.isEmpty()){ 28 | TreeNode n=q.poll(); 29 | if(n.val!=root.val){ 30 | return false; 31 | } 32 | if(n.left!=null){ 33 | q.add(n.left); 34 | } 35 | 36 | if(n.right!=null){ 37 | q.add(n.right); 38 | } 39 | } 40 | return true; 41 | } 42 | 43 | 44 | public boolean dfs(TreeNode n,int val){ 45 | if(n==null){ 46 | return true; 47 | } 48 | 49 | if(n.val!=val){ 50 | return false; 51 | } 52 | 53 | return dfs(n.left,val)&&dfs(n.right,val); 54 | 55 | } 56 | 57 | public boolean isUnivalTree2(TreeNode root) { 58 | 59 | return dfs(root,root.val); 60 | } 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/leetcode/medium/math/TinyURL.java: -------------------------------------------------------------------------------- 1 | package leetcode.medium.math; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /*** 7 | * 8 | *https://leetcode.com/problems/encode-and-decode-tinyurl/ 9 | * 10 | * 设计一个算法对长url进行短url的转换 11 | * 12 | * 13 | */ 14 | public class TinyURL { 15 | 16 | 17 | static final Map map = new HashMap<>(); 18 | static final String BASE_HOST = "http://tinyurl.com/"; 19 | 20 | // Encodes a URL to a shortened URL. 21 | public String encode(String longUrl) { 22 | String shortUrl=BASE_HOST+longUrl.hashCode(); 23 | map.put(shortUrl,longUrl); 24 | return shortUrl; 25 | } 26 | 27 | // Decodes a shortened URL to its original URL. 28 | public String decode(String shortUrl) { 29 | return map.get(shortUrl); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/memory_gc/DemoTest.java: -------------------------------------------------------------------------------- 1 | package memory_gc; 2 | 3 | /*** 4 | * 5 | * 展示堆栈数据的分布 6 | * 7 | */ 8 | public class DemoTest { 9 | 10 | int y;// 分布在堆上 11 | 12 | public static void main(String[] args) { 13 | 14 | int x=1; //分配在栈上 15 | String name=new String("cat");//数据在堆上,name变量的指针在栈上 16 | String address="北京";//数据在常量池,属于堆空间,指针在栈 17 | Integer price=4;//包装类型同样是引用类型,编译时会自动装拆相,所以数据在堆上,指针在栈 18 | } 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/memory_gc/MemoryTest.java: -------------------------------------------------------------------------------- 1 | package memory_gc; 2 | 3 | public class MemoryTest { 4 | 5 | private static final int _1MB = 1024 * 1024; 6 | 7 | public static 8 | byte[] my=new byte[100*_1MB]; //100M 9 | 10 | 11 | public static void main(String[] args) throws InterruptedException { 12 | 13 | 14 | System.out.println(my.length); 15 | 16 | Thread.currentThread().join(); 17 | 18 | } 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/netty/time_server/TimeClientHandler.java: -------------------------------------------------------------------------------- 1 | package netty.time_server; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | 7 | import java.util.Date; 8 | 9 | public class TimeClientHandler extends ChannelInboundHandlerAdapter { 10 | 11 | 12 | @Override 13 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 14 | ByteBuf m=(ByteBuf)msg; 15 | try{ 16 | long currentTimeMills= (m.readUnsignedInt() - 2208988800L) * 1000L; 17 | System.out.println(new Date(currentTimeMills)); 18 | ctx.close(); 19 | }finally { 20 | m.release(); 21 | } 22 | } 23 | 24 | 25 | @Override 26 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 27 | cause.printStackTrace(); 28 | ctx.close(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/netty/time_server/TimeServerHandler.java: -------------------------------------------------------------------------------- 1 | package netty.time_server; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelFutureListener; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelInboundHandlerAdapter; 8 | 9 | public class TimeServerHandler extends ChannelInboundHandlerAdapter { 10 | 11 | 12 | @Override 13 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 14 | final ByteBuf time=ctx.alloc().buffer(4); 15 | time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); 16 | 17 | final ChannelFuture f=ctx.writeAndFlush(time); 18 | 19 | f.addListener(new ChannelFutureListener() { 20 | @Override 21 | public void operationComplete(ChannelFuture future) throws Exception { 22 | assert f==future; 23 | ctx.close(); 24 | } 25 | }); 26 | 27 | } 28 | 29 | @Override 30 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 31 | cause.printStackTrace(); 32 | ctx.close(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/proxy/cglib_dynamic_proxy/Hello.java: -------------------------------------------------------------------------------- 1 | package proxy.cglib_dynamic_proxy; 2 | 3 | import java.io.Serializable; 4 | 5 | // 必须实现序列化,否则无法将字节码保存到磁盘上 6 | public class Hello implements Serializable { 7 | 8 | public String sayHello(String str){ 9 | System.out.println("hello"); 10 | return "hello world!"+str; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/proxy/cglib_dynamic_proxy/MyInterceptor.java: -------------------------------------------------------------------------------- 1 | package proxy.cglib_dynamic_proxy; 2 | 3 | import net.sf.cglib.proxy.MethodInterceptor; 4 | import net.sf.cglib.proxy.MethodProxy; 5 | import proxy.jdk_dynamic_proxy.SaveClassToDisk; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | public class MyInterceptor implements MethodInterceptor { 10 | 11 | @Override 12 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 13 | 14 | System.out.println(o.getClass().getName()); 15 | System.out.println("调用了"); 16 | 17 | // methodProxy.invokeSuper(o,objects); 18 | // SaveClassToDisk.save(o.getClass().getName(),o.getClass(),"G:/proxy.cglib_proxy.Hello$$EnhancerByCGLIB$$733c4bc0.class"); 19 | SaveClassToDisk.save(o.getClass().getName(),o.getClass(),"./gxx.class"); 20 | return null; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/proxy/cglib_dynamic_proxy/TestMain.java: -------------------------------------------------------------------------------- 1 | package proxy.cglib_dynamic_proxy; 2 | 3 | import net.sf.cglib.core.DefaultGeneratorStrategy; 4 | import net.sf.cglib.proxy.Enhancer; 5 | 6 | import java.io.FileOutputStream; 7 | 8 | public class TestMain { 9 | 10 | public static void main(String[] args) { 11 | 12 | 13 | Enhancer enhancer=new Enhancer(); 14 | enhancer.setSuperclass(Hello.class); 15 | enhancer.setCallback(new MyInterceptor()); 16 | //保存生成的字节码文件到磁盘上 17 | enhancer.setStrategy(new DefaultGeneratorStrategy(){ 18 | @Override 19 | protected byte[] transform(byte[] b) throws Exception { 20 | FileOutputStream out = new FileOutputStream("./hello.class"); 21 | //将代理对象的class字节码写到硬盘上 22 | out.write(b); 23 | out.flush(); 24 | out.close(); 25 | 26 | return super.transform(b); 27 | } 28 | }); 29 | Hello hello= (Hello) enhancer.create(); 30 | 31 | hello.sayHello("你好"); 32 | 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/proxy/jdk_dynamic_proxy/CountTimeProxyInvocation.java: -------------------------------------------------------------------------------- 1 | package proxy.jdk_dynamic_proxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | import java.util.Arrays; 6 | 7 | public class CountTimeProxyInvocation implements InvocationHandler { 8 | 9 | private Object target; 10 | 11 | public CountTimeProxyInvocation(Object target) { 12 | this.target = target; 13 | } 14 | 15 | 16 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 17 | // System.out.println(proxy+" "+method+" "+ args.toString()); 18 | System.out.println("name:"+proxy.getClass().getName()); 19 | SaveClassToDisk.save(proxy.getClass().getName(),proxy.getClass(),"G:/$Proxy0.class"); 20 | System.out.println(method+" "+Arrays.toString(args));//传入的参数类型 21 | long start=System.nanoTime(); 22 | System.out.println("调用之前......."); 23 | // Object result=ms.get(method.getName()).invoke(target,args); 24 | Object result=method.invoke(target,args); 25 | long cost=System.nanoTime()-start; 26 | System.out.println("调用之后,"+method.getName()+" 耗时: "+cost+" ns"); 27 | 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/proxy/jdk_dynamic_proxy/SaveClassToDisk.java: -------------------------------------------------------------------------------- 1 | package proxy.jdk_dynamic_proxy; 2 | 3 | 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | 7 | /*** 8 | * 将class文件保存到磁盘上 9 | */ 10 | public class SaveClassToDisk { 11 | 12 | 13 | public static void save(String className, Class cl, String path){ 14 | //用于生产代理对象的字节码,在编译时候报错,所以放弃使用 15 | // byte[] classFile = ProxyGenerator.generateProxyClass(className, cl.getInterfaces()); 16 | byte[] classFile = null; 17 | FileOutputStream out = null; 18 | try { 19 | out = new FileOutputStream(path); 20 | //将代理对象的class字节码写到硬盘上 21 | out.write(classFile); 22 | out.flush(); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } finally { 26 | try { 27 | out.close(); 28 | } catch (IOException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | } 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/proxy/jdk_dynamic_proxy/SimpleInvocation.java: -------------------------------------------------------------------------------- 1 | package proxy.jdk_dynamic_proxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | 6 | public class SimpleInvocation implements InvocationHandler { 7 | 8 | 9 | 10 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 11 | System.out.println(" method: "+method.getName()); 12 | show(); 13 | return 42; 14 | 15 | } 16 | 17 | public void show(){ 18 | 19 | System.out.println("123"); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/proxy/jdk_dynamic_proxy/TestSimpleProxy.java: -------------------------------------------------------------------------------- 1 | package proxy.jdk_dynamic_proxy; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.lang.reflect.Proxy; 6 | import java.util.Map; 7 | 8 | public class TestSimpleProxy { 9 | 10 | public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, 11 | InstantiationException { 12 | 13 | 14 | // Map proxyInstance= Proxy.newProxyInstance() 15 | 16 | 17 | InvocationHandler handler=new SimpleInvocation(); 18 | 19 | Class proxyClass=Proxy.getProxyClass(Map.class.getClassLoader(),Map.class); 20 | 21 | Map map=(Map) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler); 22 | 23 | map.put("xt","x"); 24 | 25 | 26 | // 方式2 27 | 28 | 29 | Map map2=(Map) Proxy.newProxyInstance(TestSimpleProxy.class.getClassLoader(),new Class[]{Map.class},handler); 30 | 31 | map.put("1","2"); 32 | 33 | 34 | 35 | 36 | 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/proxy/static_proxy/Animal.java: -------------------------------------------------------------------------------- 1 | package proxy.static_proxy; 2 | 3 | public interface Animal { 4 | 5 | 6 | public String run(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/proxy/static_proxy/Cat.java: -------------------------------------------------------------------------------- 1 | package proxy.static_proxy; 2 | 3 | public class Cat implements Animal { 4 | 5 | 6 | @Override 7 | public String run() { 8 | return "小猫跳......"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/proxy/static_proxy/Dog.java: -------------------------------------------------------------------------------- 1 | package proxy.static_proxy; 2 | 3 | public class Dog implements Animal { 4 | 5 | @Override 6 | public String run() { 7 | return " 小狗跑..... "; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/proxy/static_proxy/ProxyRole.java: -------------------------------------------------------------------------------- 1 | package proxy.static_proxy; 2 | 3 | public class ProxyRole implements Animal { 4 | 5 | private Animal proxy; 6 | 7 | public ProxyRole(Animal proxy) { 8 | this.proxy = proxy; 9 | } 10 | 11 | @Override 12 | public String run() { 13 | 14 | System.out.println(" before execute...... "); 15 | String result=proxy.run(); 16 | System.out.println(result); 17 | System.out.println(" after execute...... "); 18 | 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/proxy/static_proxy/TestMain.java: -------------------------------------------------------------------------------- 1 | package proxy.static_proxy; 2 | 3 | /*** 4 | * 静态代理展示 5 | */ 6 | public class TestMain { 7 | 8 | 9 | public static void main(String[] args) { 10 | 11 | //真实角色 12 | Animal dog=new Dog(); 13 | //代理角色 14 | ProxyRole proxyRole=new ProxyRole(dog); 15 | //代替执行 16 | proxyRole.run(); 17 | 18 | System.out.println("======================================="); 19 | //真实角色 20 | Animal cat=new Cat(); 21 | //代理角色 22 | proxyRole=new ProxyRole(cat); 23 | //代替执行 24 | proxyRole.run(); 25 | 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/reflection/Person.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | public class Person { 4 | 5 | private String name; 6 | 7 | private int age; 8 | 9 | public Person() { 10 | } 11 | 12 | public Person(String name, int age) { 13 | this.name = name; 14 | this.age = age; 15 | 16 | System.out.println("name: "+name+" age: "+age); 17 | } 18 | 19 | public String address="北京"; 20 | 21 | String id; 22 | 23 | 24 | public void speak(String place,String status,int day){ 25 | 26 | System.out.println(place+" "+status+" "+day); 27 | 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/reflection/ReflectionDemo1.java: -------------------------------------------------------------------------------- 1 | package reflection; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public class ReflectionDemo1 { 6 | 7 | public static void m4() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | 14 | Method[] methods = ReflectionDemo1.class.getMethods(); 15 | 16 | for (Method method : methods) { 17 | 18 | System.out.println(method.getName()); 19 | } 20 | 21 | } 22 | 23 | public void m1() { 24 | 25 | } 26 | 27 | public void m2() { 28 | 29 | } 30 | 31 | public void m3() { 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/reflection/base/BaseClass.java: -------------------------------------------------------------------------------- 1 | package reflection.base; 2 | 3 | public class BaseClass { 4 | 5 | public int baseInt; 6 | 7 | private static void method3() { 8 | System.out.println("Method3"); 9 | } 10 | 11 | public static int method5() { 12 | System.out.println("Method5"); 13 | return 0; 14 | } 15 | 16 | public int method4() { 17 | System.out.println("Method4"); 18 | return 0; 19 | } 20 | 21 | public int method7() { 22 | System.out.println("Method7"); 23 | return 0; 24 | } 25 | 26 | void method6() { 27 | System.out.println("Method6"); 28 | } 29 | 30 | 31 | //member public enum 32 | public enum BaseClassMemberEnum { 33 | } 34 | 35 | // inner public class 36 | public class BaseClassInnerClass { 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/reflection/base/BaseInterface.java: -------------------------------------------------------------------------------- 1 | package reflection.base; 2 | 3 | public interface BaseInterface { 4 | 5 | public int interfaceInt = 0; 6 | 7 | void method1(); 8 | 9 | int method2(String str); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/class/Demo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/class/Demo.class -------------------------------------------------------------------------------- /src/main/resources/class/Demo.java: -------------------------------------------------------------------------------- 1 | public class Demo{ 2 | 3 | public Demo(){ 4 | System.out.println(" Demo构造函数被初始化了....... "); 5 | } 6 | 7 | 8 | public void say(){ 9 | System.out.println("Say Hello ........."); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/class/Singleton.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/class/Singleton.class -------------------------------------------------------------------------------- /src/main/resources/pic/Java并发知识全景.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/pic/Java并发知识全景.png -------------------------------------------------------------------------------- /src/main/resources/pic/jvm运行区域.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/pic/jvm运行区域.jpg -------------------------------------------------------------------------------- /src/main/resources/pic/sub-thread.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/pic/sub-thread.jpg -------------------------------------------------------------------------------- /src/main/resources/pic/threadpool_v2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/pic/threadpool_v2.jpg -------------------------------------------------------------------------------- /src/main/resources/pic/数据类型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qindongliang/Java-Note/539068105a28c959879c6507731295c8d834517f/src/main/resources/pic/数据类型.png -------------------------------------------------------------------------------- /src/test/java/TestStr.java: -------------------------------------------------------------------------------- 1 | import java.util.concurrent.atomic.AtomicInteger; 2 | 3 | /** 4 | * Created by Administrator on 2018/7/12. 5 | */ 6 | public class TestStr { 7 | 8 | public static void main(String[] args) throws InterruptedException { 9 | 10 | 11 | AtomicInteger atomicInteger=new AtomicInteger(); 12 | 13 | 14 | Runnable runnable=new Runnable() { 15 | @Override 16 | public void run() { 17 | for(int i=1;i<=10000;i++){ 18 | atomicInteger.getAndIncrement(); 19 | } 20 | 21 | } 22 | }; 23 | 24 | Thread t1=new Thread(runnable); 25 | Thread t2=new Thread(runnable); 26 | Thread t3=new Thread(runnable); 27 | 28 | t1.start(); 29 | t2.start(); 30 | t3.start(); 31 | 32 | t1.join(); 33 | t2.join(); 34 | t3.join(); 35 | 36 | 37 | System.out.println(atomicInteger.get()); 38 | 39 | 40 | } 41 | } 42 | --------------------------------------------------------------------------------