Java Code Examples for java.util.TreeMap#firstKey()

The following examples show how to use java.util.TreeMap#firstKey() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LinkDocHandler.java    From io with Apache License 2.0 6 votes vote down vote up
/**
 * コンストラクタ.
 * @param srcHandler OEntityDocHandler
 * @param targetSetName ターゲット側のEntitySet名
 * @param targetEntityTypeId ターゲット側のEntityTypeID
 */
public NtoNQueryParameter(
        final EntitySetDocHandler srcHandler,
        final String targetSetName,
        final String targetEntityTypeId) {
    String srcSetName = srcHandler.getType();
    String srcId = srcHandler.getId();

    TreeMap<String, String> tm = new TreeMap<String, String>();
    if (srcSetName.equals(UserDataODataProducer.USER_ODATA_NAMESPACE)) {
        tm.put(srcHandler.getEntityTypeId(), srcId);
        tm.put(targetEntityTypeId, "");
    } else {
        tm.put(srcSetName, srcId);
        tm.put(targetSetName, "");
    }
    this.t1 = tm.firstKey();
    this.t2 = tm.lastKey();
    this.k1 = tm.get(t1);
    this.k2 = tm.get(t2);
}
 
Example 2
Source File: LinkDocHandler.java    From io with Apache License 2.0 6 votes vote down vote up
/**
 * コンストラクタ.
 * @param srcHandler OEntityDocHandler
 * @param tgtHandler OEntityDocHandler
 */
public LinkDocHandler(final EntitySetDocHandler srcHandler, final EntitySetDocHandler tgtHandler) {
    this.cellId = srcHandler.getCellId();
    this.boxId = srcHandler.getBoxId();
    this.nodeId = srcHandler.getNodeId();
    String srcType = srcHandler.getType();
    String srcId = srcHandler.getId();
    String tgtType = tgtHandler.getType();
    String tgtId = tgtHandler.getId();

    // ES 保存時の一意キー作成
    TreeMap<String, String> tm = new TreeMap<String, String>();
    tm.put(srcType, srcId);
    tm.put(tgtType, tgtId);

    this.ent1Type = tm.firstKey();
    this.ent2Type = tm.lastKey();
    this.ent1Key = tm.get(ent1Type);
    this.ent2Key = tm.get(ent2Type);
    this.id = this.createLinkId();
    long dateTime = new Date().getTime();
    this.published = dateTime;
    this.updated = dateTime;
}
 
Example 3
Source File: Renderer.java    From gpx-animator with Apache License 2.0 6 votes vote down vote up
private void mergeConnectedSpans(final List<Long[]> spanList, final TreeMap<Long, Point2D> timePointMap) {
    long t0 = timePointMap.firstKey();
    long t1 = timePointMap.lastKey() + cfg.getTailDuration();

    for (final Iterator<Long[]> iter = spanList.iterator(); iter.hasNext();) {
        final Long[] span = iter.next();
        if (t0 > span[0] && t1 < span[1]) {
            // swallowed
            return;
        }

        if (t0 < span[0] && t1 > span[1]) {
            // swallows
            iter.remove();
        } else if (t1 > span[0] && t1 < span[1]) {
            t1 = span[1];
            iter.remove();
        } else if (t0 < span[1] && t0 > span[0]) {
            t0 = span[0];
            iter.remove();
        }
    }

    spanList.add(new Long[]{t0, t1});
}
 
Example 4
Source File: 10132 File Fragmentation.java    From UVA with GNU General Public License v3.0 5 votes vote down vote up
public static void main (String [] args) throws Exception {
	BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	int testCaseCount=Integer.parseInt(br.readLine());
	br.readLine(); //empty line
	for (int testCase=0;testCase<testCaseCount;testCase++) {
		TreeMap<Integer,HashMap<String,Integer>> map=new TreeMap<>();
		String s;
		int sCount=0;
		while (true) {
			s=br.readLine();
			if (s!=null && s.length()>0) {
				addToMap(map,s);
				sCount++;
			} else {
				break;
			}
		}
		
		int minLength=map.firstKey();
		int maxLength=map.lastKey();
		TreeSet<String> possibleSol=new TreeSet<>();
		for (String s1 : map.get(minLength).keySet()) for (String s2 : map.get(maxLength).keySet()) {
			possibleSol.add(s1+s2);
			possibleSol.add(s2+s1);
		}
		
		boolean flag=false;
		for (String sol : possibleSol) {
			flag=solutionOK(sol,map,sCount/2);
			if (flag) {
				printSolution(testCase,sol);
				break;
			}
		}

		if (!flag) printSolution(testCase,possibleSol.iterator().next());
	}
}
 
Example 5
Source File: OmemoStore.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Remove the oldest signedPreKey until there are only MAX_NUMBER_OF_STORED_SIGNED_PREKEYS left.
 *
 * @param userDevice our OmemoDevice.
 *
 * @throws IOException if an I/O error occurred.
 */
private void removeOldSignedPreKeys(OmemoDevice userDevice) throws IOException {
    if (OmemoConfiguration.getMaxNumberOfStoredSignedPreKeys() <= 0) {
        return;
    }

    TreeMap<Integer, T_SigPreKey> signedPreKeys = loadOmemoSignedPreKeys(userDevice);

    for (int i = 0; i < signedPreKeys.keySet().size() - OmemoConfiguration.getMaxNumberOfStoredSignedPreKeys(); i++) {
        int keyId = signedPreKeys.firstKey();
        LOGGER.log(Level.INFO, "Remove signedPreKey " + keyId + ".");
        removeOmemoSignedPreKey(userDevice, i);
        signedPreKeys = loadOmemoSignedPreKeys(userDevice);
    }
}
 
Example 6
Source File: LinkDocHandler.java    From io with Apache License 2.0 5 votes vote down vote up
/**
 * 検索結果からLinkDocHandlerを生成するコンストラクタ.
 * @param searchHit 検索結果データ
 */
public LinkDocHandler(final DcSearchHit searchHit) {
    this.id = searchHit.getId();

    Map<String, Object> source = searchHit.getSource();
    this.cellId = source.get(KEY_CELL_ID).toString();
    if (source.containsKey(KEY_BOX_ID) && source.get(KEY_BOX_ID) != null) {
        this.boxId = source.get(KEY_BOX_ID).toString();
    }
    if (source.containsKey(KEY_NODE_ID) && source.get(KEY_NODE_ID) != null) {
        this.nodeId = source.get(KEY_NODE_ID).toString();
    }

    // ES 保存時の一意キー作成
    String srcType = source.get(KEY_ENT1_TYPE).toString();
    String srcId = source.get(KEY_ENT1_ID).toString();
    String tgtType = source.get(KEY_ENT2_TYPE).toString();
    String tgtId = source.get(KEY_ENT2_ID).toString();
    TreeMap<String, String> tm = new TreeMap<String, String>();
    tm.put(srcType, srcId);
    tm.put(tgtType, tgtId);

    this.ent1Type = tm.firstKey();
    this.ent2Type = tm.lastKey();
    this.ent1Key = tm.get(ent1Type);
    this.ent2Key = tm.get(ent2Type);
    this.published = Long.parseLong(source.get(KEY_PUBLISHED).toString());
    this.updated = Long.parseLong(source.get(KEY_UPDATED).toString());
}
 
Example 7
Source File: BinarySearchIndexTest.java    From chipster with MIT License 5 votes vote down vote up
private static void testLineIdentifiers(Index index, long startPosition) throws IOException,
		GBrowserException {
	
	//Line identifier must be same regardless of the line position in the request region 
	
	//First line of request region
	Region region;
	region = new Region(startPosition, startPosition + 100, new Chromosome("chr1"));
	TreeMap<IndexKey, String> lineMap = index.getFileLines(region);
	IndexKey id1 = lineMap.firstKey();
	
	//Last line  of request region
	region = new Region(startPosition - 100, startPosition + 1, new Chromosome("chr1"));
	lineMap = index.getFileLines(region);
	IndexKey id2 = lineMap.lastKey();
	
	//In the middle of request region
	region = new Region(startPosition - 100, startPosition + 100, new Chromosome("chr1"));
	lineMap = index.getFileLines(region);
	IndexKey fromKey = new IndexKey(new BpCoord(startPosition, new Chromosome("chr1")), 0);
	IndexKey toKey = new IndexKey(new BpCoord(startPosition, new Chromosome("chr1")), Long.MAX_VALUE);
	SortedMap<IndexKey, String> subMap = lineMap.subMap(fromKey, toKey);		
	IndexKey id3 = subMap.firstKey();
	
	Assert.assertEquals(id1, id2);
	Assert.assertEquals(id2, id3);
}
 
Example 8
Source File: OrderedTombstoneMap.java    From gemfirexd-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Remove a version tag from the map.
 */
public Map.Entry<VersionTag, T> take() {
  if(tombstoneMap.isEmpty()) {
    //if there are no more entries, return null;
    return null;
  } else {
    //Otherwise, look at all of the members and find the tag with the 
    //lowest timestamp.
    long lowestTimestamp = Long.MAX_VALUE;
    TreeMap<VersionTag, T> lowestMap = null;
    for(TreeMap<VersionTag, T> memberMap: tombstoneMap.values()) {
      VersionTag firstTag = memberMap.firstKey();
      long stamp = firstTag.getVersionTimeStamp();
      if(stamp < lowestTimestamp) {
        lowestTimestamp = stamp;
        lowestMap = memberMap;
      }
    }
    if(lowestMap == null) {
      return null;
    }
    //Remove the lowest entry
    Entry<VersionTag, T> result = lowestMap.firstEntry();
    lowestMap.remove(result.getKey());
    if(lowestMap.isEmpty()) {
      //if this is the last entry from a given member,
      //the map for that member
      tombstoneMap.remove(result.getKey().getMemberID());
    }
    
    return result;
  }
}
 
Example 9
Source File: Renderer.java    From gpx-animator with Apache License 2.0 5 votes vote down vote up
private void trimGpxData(final TreeMap<Long, Point2D> timePointMap, final TrackConfiguration trackConfiguration) {

        final Long trimGpxStart = trackConfiguration.getTrimGpxStart();
        if (trimGpxStart != null && trimGpxStart > 0 && timePointMap.size() > 0) {
            final Long skipToTime = timePointMap.firstKey() + trimGpxStart;
            timePointMap.entrySet().removeIf(e -> e.getKey() < skipToTime);
        }

        final Long trimGpxEnd = trackConfiguration.getTrimGpxEnd();
        if (trimGpxEnd != null && trimGpxEnd > 0 && timePointMap.size() > 0) {
            final Long skipAfterTime = timePointMap.lastKey() - trimGpxEnd;
            timePointMap.entrySet().removeIf(e -> e.getKey() > skipAfterTime);
        }
    }
 
Example 10
Source File: 11136 Hoax or What.java    From UVA with GNU General Public License v3.0 5 votes vote down vote up
public static void main (String [] args) throws IOException {
	BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	String s;
	
	while (!(s=br.readLine()).equals("0")) {
		int N=Integer.parseInt(s);
		long cost=0; //wtf.
		TreeMap<Integer,Integer> map=new TreeMap<>();
		for (int i=0;i<N;i++) {
			StringTokenizer st=new StringTokenizer(br.readLine());
			int k=Integer.parseInt(st.nextToken());
			for (int i2=0;i2<k;i2++) {
				int num=Integer.parseInt(st.nextToken());
				map.put(num,map.getOrDefault(num,0)+1);
			}
			
			int highest=map.lastKey();
			if (map.get(highest)==1) map.remove(highest);
			else map.put(highest,map.get(highest)-1);
			
			int lowest=map.firstKey();
			if (map.get(lowest)==1) map.remove(lowest);
			else map.put(lowest,map.get(lowest)-1);
			
			cost+=(highest-lowest);
		}
		System.out.println(cost);
	}
}
 
Example 11
Source File: OpenUDID_manager.java    From Cangol-appcore with Apache License 2.0 5 votes vote down vote up
private void getMostFrequentOpenUDID() {
	if (mReceivedOpenUDIDs.isEmpty() == false) {
		final TreeMap<String,Integer> sorted_OpenUDIDS = new TreeMap(new ValueComparator());
		sorted_OpenUDIDS.putAll(mReceivedOpenUDIDs);
       
		OpenUDID = sorted_OpenUDIDS.firstKey();
	}
}
 
Example 12
Source File: TreeMapDemo.java    From javacore with Creative Commons Attribution Share Alike 4.0 International 5 votes vote down vote up
public static void main(String[] args) {
    TreeMap<Integer, String> treeMap = new TreeMap<>();
    for (int i = 0; i < chars.length; i++) {
        treeMap.put(i, chars[i]);
    }
    System.out.println(treeMap);
    Integer low = treeMap.firstKey();
    Integer high = treeMap.lastKey();
    System.out.println(low);
    System.out.println(high);
    Iterator<Integer> it = treeMap.keySet().iterator();
    for (int i = 0; i <= 6; i++) {
        if (i == 3) {
            low = it.next();
        }
        if (i == 6) {
            high = it.next();
        } else {
            it.next();
        }
    }
    System.out.println(low);
    System.out.println(high);
    System.out.println(treeMap.subMap(low, high));
    System.out.println(treeMap.headMap(high));
    System.out.println(treeMap.tailMap(low));
}
 
Example 13
Source File: WarpSigns.java    From askyblock with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @return Sorted list of warps with most recent players listed first
 */
public Collection<UUID> listSortedWarps() {
    // Bigger value of time means a more recent login
    TreeMap<Long, UUID> map = new TreeMap<>();
    Iterator<Entry<UUID, Location>> it = warpList.entrySet().iterator();
    while (it.hasNext()) {
        Entry<UUID, Location> en = it.next();
        // Check if the location of the warp still exists, if not, delete it
        if (en.getValue() == null) {
            it.remove();
        } else {
            UUID uuid = en.getKey();
            // If never played, will be zero
            long lastPlayed = plugin.getServer().getOfflinePlayer(uuid).getLastPlayed();
            // This aims to avoid the chance that players logged off at exactly the same time
            if (!map.isEmpty() && map.containsKey(lastPlayed)) {
                lastPlayed = map.firstKey() - 1;
            }
            map.put(lastPlayed, uuid);
        }
    }

    Collection<UUID> result = map.descendingMap().values();
    // Fire event
    WarpListEvent event = new WarpListEvent(plugin, result);
    plugin.getServer().getPluginManager().callEvent(event);
    // Get the result of any changes by listeners
    result = event.getWarps();
    return result;
}
 
Example 14
Source File: SmapResolver.java    From netbeans with Apache License 2.0 5 votes vote down vote up
/** 
 * get primary jsp filename
 */
public String getPrimaryJspFileName() {
    TreeMap tm = new TreeMap(fsection);
    Object o = tm.firstKey();
    String s = (String)fsection.get(o);
    return s;
}
 
Example 15
Source File: ShardUtil.java    From star-zone with Apache License 2.0 5 votes vote down vote up
/**
 * 沿环的顺时针找到节点
 *
 * @param map
 * @param key
 * @return
 */
public static String doGetTableName(TreeMap<Long, String> map, String key) {
    final Long hash = alg.hash(key);
    Long target = hash;
    if (!map.containsKey(hash)) {
        target = map.ceilingKey(hash);
        if (target == null && !map.isEmpty()) {
            target = map.firstKey();
        }
    }
    return map.get(target);
}
 
Example 16
Source File: CacheTableFIFO.java    From siddhi with Apache License 2.0 5 votes vote down vote up
@Override
public void deleteEntriesUsingCachePolicy(int numRowsToDelete) {
    IndexEventHolder indexEventHolder = (IndexEventHolder) stateHolder.getState().getEventHolder();
    if (numRowsToDelete >= indexEventHolder.size()) {
        indexEventHolder.deleteAll();
    } else {
        Set<Object> keys = indexEventHolder.getAllPrimaryKeyValues();
        TreeMap<Long, Object> toDelete = new TreeMap<>();
        for (Object key : keys) {
            if (toDelete.size() < numRowsToDelete) {
                toDelete.put((Long) indexEventHolder.getEvent(key).getOutputData()[cachePolicyAttributePosition],
                        key);
            } else {
                Long timestamp = (Long) indexEventHolder.getEvent(key).
                        getOutputData()[cachePolicyAttributePosition];
                Long firstKey = toDelete.firstKey();
                if (timestamp < firstKey) {
                    toDelete.remove(firstKey);
                    toDelete.put(timestamp, key);
                }
            }
        }
        for (Object deleteKey : toDelete.values()) {
            if (deleteKey != null) {
                indexEventHolder.deleteEvent(deleteKey);
            }
        }
    }
}
 
Example 17
Source File: ShardUtil.java    From star-zone with Apache License 2.0 5 votes vote down vote up
/**
 * 沿环的顺时针找到节点
 *
 * @param map
 * @param key
 * @return
 */
public static String doGetTableName(TreeMap<Long, String> map, String key) {
    final Long hash = alg.hash(key);
    Long target = hash;
    if (!map.containsKey(hash)) {
        target = map.ceilingKey(hash);
        if (target == null && !map.isEmpty()) {
            target = map.firstKey();
        }
    }
    return map.get(target);
}
 
Example 18
Source File: CourseOverGroundStatisticTest.java    From AisAbnormal with GNU Lesser General Public License v3.0 4 votes vote down vote up
@Test
public void testNewShipCountIsCreated() {
    // Setup expectations
    final ArgumentCaptor<StatisticData> statistics = ArgumentCaptor.forClass(StatisticData.class);
    context.checking(new Expectations() {{
        oneOf(trackingService).registerSubscriber(statistic);
        ignoring(statisticsService).incStatisticStatistics(with(CourseOverGroundStatistic.STATISTIC_NAME), with(any(String.class)));

        oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)));
        oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics.getMatcher()));
    }});

    // Execute
    statistic.start();
    statistic.onCellIdChanged(event);

    // Main assertations
    CourseOverGroundStatisticData capturedStatisticData = (CourseOverGroundStatisticData) statistics.getCapturedObject();

    context.assertIsSatisfied();

    TreeMap<Integer, TreeMap<Integer, TreeMap<Integer, HashMap<String, Integer>>>> data = capturedStatisticData.getData();

    assertEquals(1, data.size()); // Assert one statistic recorded
    int shipTypeBucket = data.firstKey();
    assertEquals(3, shipTypeBucket);
    int shipSizeBucket = data.get(shipTypeBucket).firstKey();
    assertEquals(3, shipSizeBucket);
    int cogBucket = data.get(shipTypeBucket).get(shipSizeBucket).firstKey();
    assertEquals(7, cogBucket);

    int numberOfStats = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).size();
    assertEquals(1, numberOfStats);
    String statName = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).keySet().iterator().next();
    Object statValue = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).get(statName);
    assertEquals(Integer.class, statValue.getClass());
    assertEquals(1, statValue);

    // Other assertations now we're here
    assertEquals(CourseOverGroundStatisticData.class, statistics.getCapturedObject().getClass());
    assertEquals("type", capturedStatisticData.getMeaningOfKey1());
    assertEquals("size", capturedStatisticData.getMeaningOfKey2());
    assertEquals(TreeMap.class, statistics.getCapturedObject().getData().getClass());
    assertEquals(CourseOverGroundStatisticData.STAT_SHIP_COUNT, statName);
}
 
Example 19
Source File: CourseOverGroundStatisticTest.java    From AisAbnormal with GNU Lesser General Public License v3.0 4 votes vote down vote up
@Test
public void testExistingShipCountIsUpdated() {
    final CourseOverGroundStatisticData existingStatisticData = CourseOverGroundStatisticData.create();
    existingStatisticData.setValue(3-1, 3-1, 7-1, CourseOverGroundStatisticData.STAT_SHIP_COUNT, 1);

    final ArgumentCaptor<StatisticData> statistics1 = ArgumentCaptor.forClass(StatisticData.class);
    final ArgumentCaptor<StatisticData> statistics2 = ArgumentCaptor.forClass(StatisticData.class);
    context.checking(new Expectations() {{
        oneOf(trackingService).registerSubscriber(statistic);
        ignoring(statisticsService).incStatisticStatistics(with(CourseOverGroundStatistic.STATISTIC_NAME), with(any(String.class)));

        oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)));
        will(returnValue(null));
        oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics1.getMatcher()));

        oneOf(statisticsRepository).getStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)));
        will(returnValue(existingStatisticData));
        oneOf(statisticsRepository).putStatisticData(with(CourseOverGroundStatistic.STATISTIC_NAME), (Long) with(track.getProperty(Track.CELL_ID)), with(statistics2.getMatcher()));
    }});

    // Execute
    statistic.start();
    statistic.onCellIdChanged(event);
    statistic.onCellIdChanged(event);

    // Assert expectations and captured values
    context.assertIsSatisfied();
    // TODO assertEquals(CourseOverGroundStatistic.STATISTIC_NAME, statistics2.getCapturedObject().getStatisticName());
    assertEquals(CourseOverGroundStatisticData.class, statistics2.getCapturedObject().getClass());
    CourseOverGroundStatisticData capturedStatisticData = (CourseOverGroundStatisticData) statistics2.getCapturedObject();
    assertEquals("type", capturedStatisticData.getMeaningOfKey1());
    assertEquals("size", capturedStatisticData.getMeaningOfKey2());
    assertEquals(TreeMap.class, statistics2.getCapturedObject().getData().getClass());
    TreeMap<Integer, TreeMap<Integer, TreeMap<Integer, HashMap<String, Integer>>>> data = capturedStatisticData.getData();
    assertEquals(1, data.size()); // Assert one statistic recorded
    int shipTypeBucket = data.firstKey();
    assertEquals(3, shipTypeBucket);
    int shipSizeBucket = data.get(shipTypeBucket).firstKey();
    assertEquals(3, shipSizeBucket);
    int cogBucket = data.get(shipTypeBucket).get(shipSizeBucket).firstKey();
    assertEquals(7, cogBucket);
    int numberOfStatsForShipTypeAndShipSize = data.get(shipTypeBucket).get(shipSizeBucket).size();
    assertEquals(1, numberOfStatsForShipTypeAndShipSize);
    String statName = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).keySet().iterator().next();
    assertEquals(CourseOverGroundStatisticData.STAT_SHIP_COUNT, statName);
    Object statValue = data.get(shipTypeBucket).get(shipSizeBucket).get(cogBucket).get(statName);
    assertEquals(2, statValue);
}
 
Example 20
Source File: TheSkylineProblem.java    From LeetCode-Sol-Res with MIT License 3 votes vote down vote up
/**
 * Heap. Line Sweep Algorithm.
 * All possible key points are at the edges of rectangle.
 * Add all top-left and top-right corners to a list.
 * Set top-left's height to negative to indicate it's left and put them before right points.
 * Sort the points by x asc, y asc.
 * Create a tree map with 0,1 in it by default.
 * Track the height of previous added key point.
 * Then for each point p in the list:
 * | If p[1] < 0, left point:
 * |   Add the height count to tree map.
 * | If p[1] > 0, right point:
 * |   Reduce the height count to tree map. If count is 1, remove the height.
 * | Get the highest by map.firstKey().
 * | If the highest != previous height, a key point found:
 * |   Add it to result.
 * |   Update previous height to current height.
 * <p>
 * Tricks:
 * 1. Store left points height as negative, then they can be distinguished from right points.
 * 2. Put height 0 count 1 into tree map as a dummy rectangle. 0 is the max height when there is no rectangle.
 * <p>
 * https://briangordon.github.io/2014/08/the-skyline-problem.html
 * <p>
 * My comments:
 * The use of tree map makes me feel a bit unnecessary, since priority queue or heap can contain duplicates.
 * A priority queue or max heap is enough.
 * The only upside is that TreeMap get/put in O(logn). Priority queue removes a specific value in O(n).
 * Because it scans through all values to find the one to remove.
 */
public List<int[]> getSkyline2(int[][] buildings) {
  // Build and sort critical points.
  List<int[]> corners = new ArrayList<>();
  for (int[] b : buildings) {
    corners.add(new int[]{b[0], -b[2]}); // Left point. Set to negative to benefit sorting.
    corners.add(new int[]{b[1], b[2]}); // Right point.
  }
  Collections.sort(corners, (a, b) -> (a[0] == b[0]) ? a[1] - b[1] : a[0] - b[0]);
  // A hash heap. Store height and number of rectangles available. Get max height by calling firstKey().
  TreeMap<Integer, Integer> heights = new TreeMap<>(Collections.reverseOrder()); // Note reverse order, max heap.
  heights.put(0, 1); // Add a dummy rectangle with height 0.
  int prevHeight = 0; // Store previous height for comparison later.
  List<int[]> skyLine = new ArrayList<>();
  for (int[] c : corners) {
    // Update heap according to left/right point.
    if (c[1] < 0) { // Height < 0, left point, add rectangle.
      heights.merge(-c[1], 1, (oldValue, newValue) -> oldValue + newValue);
    } else { // Height > 0, right point, remove rectangle.
      heights.merge(c[1], 1, (oldValue, newValue) -> oldValue.equals(newValue) ? null : oldValue - newValue);
    }
    if (prevHeight != heights.firstKey()) { // If current max height is the same as prevHeight, not a contour.
      skyLine.add(new int[]{c[0], heights.firstKey()});
      prevHeight = heights.firstKey();
    }
  }
  return skyLine;
}