Skip to content

Replace LinkedHashMap.* with Map.*, which _is_ Linked #170713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions dev/integration_tests/new_gallery/lib/data/demos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:collection';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

Expand Down Expand Up @@ -110,7 +108,7 @@ Future<void> pumpDeferredLibraries() {
class Demos {
static Map<String?, GalleryDemo> asSlugToDemoMap(BuildContext context) {
final GalleryLocalizations localizations = GalleryLocalizations.of(context)!;
return LinkedHashMap<String?, GalleryDemo>.fromIterable(
return Map<String?, GalleryDemo>.fromIterable(
all(localizations),
// ignore: avoid_dynamic_calls
key: (dynamic demo) => demo.slug as String?,
Expand Down
46 changes: 21 additions & 25 deletions dev/integration_tests/new_gallery/lib/pages/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:collection';

import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localized_locales/flutter_localized_locales.dart';
Expand Down Expand Up @@ -100,9 +98,9 @@ class _SettingsPageState extends State<SettingsPage> {

/// Create a sorted — by native name – map of supported locales to their
/// intended display string, with a system option as the first element.
LinkedHashMap<Locale, DisplayOption> _getLocaleOptions() {
final LinkedHashMap<Locale, DisplayOption> localeOptions =
LinkedHashMap<Locale, DisplayOption>.of(<Locale, DisplayOption>{
Map<Locale, DisplayOption> _getLocaleOptions() {
final Map<Locale, DisplayOption> localeOptions =
Map<Locale, DisplayOption>.of(<Locale, DisplayOption>{
systemLocaleOption: DisplayOption(
GalleryLocalizations.of(context)!.settingsSystemDefault +
(deviceLocale != null
Expand All @@ -123,7 +121,7 @@ class _SettingsPageState extends State<SettingsPage> {
compareAsciiUpperCase(l1.value.title, l2.value.title),
);

localeOptions.addAll(LinkedHashMap<Locale, DisplayOption>.fromEntries(displayLocales));
localeOptions.addAll(Map<Locale, DisplayOption>.fromEntries(displayLocales));
return localeOptions;
}

Expand All @@ -138,7 +136,7 @@ class _SettingsPageState extends State<SettingsPage> {
SettingsListItem<double?>(
title: localizations.settingsTextScaling,
selectedOption: options.textScaleFactor(context, useSentinel: true),
optionsMap: LinkedHashMap<double?, DisplayOption>.of(<double?, DisplayOption>{
optionsMap: Map<double?, DisplayOption>.of(<double?, DisplayOption>{
systemTextScaleFactorOption: DisplayOption(localizations.settingsSystemDefault),
0.8: DisplayOption(localizations.settingsTextScalingSmall),
1.0: DisplayOption(localizations.settingsTextScalingNormal),
Expand All @@ -154,15 +152,14 @@ class _SettingsPageState extends State<SettingsPage> {
SettingsListItem<CustomTextDirection?>(
title: localizations.settingsTextDirection,
selectedOption: options.customTextDirection,
optionsMap: LinkedHashMap<CustomTextDirection?, DisplayOption>.of(
<CustomTextDirection?, DisplayOption>{
CustomTextDirection.localeBased: DisplayOption(
localizations.settingsTextDirectionLocaleBased,
),
CustomTextDirection.ltr: DisplayOption(localizations.settingsTextDirectionLTR),
CustomTextDirection.rtl: DisplayOption(localizations.settingsTextDirectionRTL),
},
),
optionsMap:
Map<CustomTextDirection?, DisplayOption>.of(<CustomTextDirection?, DisplayOption>{
CustomTextDirection.localeBased: DisplayOption(
localizations.settingsTextDirectionLocaleBased,
),
CustomTextDirection.ltr: DisplayOption(localizations.settingsTextDirectionLTR),
CustomTextDirection.rtl: DisplayOption(localizations.settingsTextDirectionRTL),
}),
onOptionChanged:
(CustomTextDirection? newTextDirection) => GalleryOptions.update(
context,
Expand All @@ -187,14 +184,13 @@ class _SettingsPageState extends State<SettingsPage> {
SettingsListItem<TargetPlatform?>(
title: localizations.settingsPlatformMechanics,
selectedOption: options.platform,
optionsMap:
LinkedHashMap<TargetPlatform?, DisplayOption>.of(<TargetPlatform?, DisplayOption>{
TargetPlatform.android: DisplayOption('Android'),
TargetPlatform.iOS: DisplayOption('iOS'),
TargetPlatform.macOS: DisplayOption('macOS'),
TargetPlatform.linux: DisplayOption('Linux'),
TargetPlatform.windows: DisplayOption('Windows'),
}),
optionsMap: Map<TargetPlatform?, DisplayOption>.of(<TargetPlatform?, DisplayOption>{
TargetPlatform.android: DisplayOption('Android'),
TargetPlatform.iOS: DisplayOption('iOS'),
TargetPlatform.macOS: DisplayOption('macOS'),
TargetPlatform.linux: DisplayOption('Linux'),
TargetPlatform.windows: DisplayOption('Windows'),
}),
onOptionChanged:
(TargetPlatform? newPlatform) =>
GalleryOptions.update(context, options.copyWith(platform: newPlatform)),
Expand All @@ -204,7 +200,7 @@ class _SettingsPageState extends State<SettingsPage> {
SettingsListItem<ThemeMode?>(
title: localizations.settingsTheme,
selectedOption: options.themeMode,
optionsMap: LinkedHashMap<ThemeMode?, DisplayOption>.of(<ThemeMode?, DisplayOption>{
optionsMap: Map<ThemeMode?, DisplayOption>.of(<ThemeMode?, DisplayOption>{
ThemeMode.system: DisplayOption(localizations.settingsSystemDefault),
ThemeMode.dark: DisplayOption(localizations.settingsDarkTheme),
ThemeMode.light: DisplayOption(localizations.settingsLightTheme),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:collection';

import 'package:flutter/material.dart';

// Common constants between SlowMotionSetting and SettingsListItem.
Expand Down Expand Up @@ -81,7 +79,7 @@ class SettingsListItem<T> extends StatefulWidget {
required this.isExpanded,
});

final LinkedHashMap<T, DisplayOption> optionsMap;
final Map<T, DisplayOption> optionsMap;
final String title;
final T selectedOption;
final ValueChanged<T> onOptionChanged;
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/foundation/observer_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class ObserverList<T> extends Iterable<T> {
///
/// * [ObserverList] for a list that is fast for small numbers of observers.
class HashedObserverList<T> extends Iterable<T> {
final LinkedHashMap<T, int> _map = LinkedHashMap<T, int>();
final Map<T, int> _map = <T, int>{};

/// Adds an item to the end of this list.
///
Expand Down
5 changes: 2 additions & 3 deletions packages/flutter/lib/src/rendering/editable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/// @docImport 'package:flutter/cupertino.dart';
library;

import 'dart:collection';
import 'dart:math' as math;
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, LineMetrics, SemanticsInputType, TextBox;

Expand Down Expand Up @@ -1308,7 +1307,7 @@ class RenderEditable extends RenderBox
// can be re-used when [assembleSemanticsNode] is called again. This ensures
// stable ids for the [SemanticsNode]s of [TextSpan]s across
// [assembleSemanticsNode] invocations.
LinkedHashMap<Key, SemanticsNode>? _cachedChildNodes;
Map<Key, SemanticsNode>? _cachedChildNodes;

/// Returns a list of rects that bound the given selection, and the text
/// direction. The text direction is used by the engine to calculate
Expand Down Expand Up @@ -1432,7 +1431,7 @@ class RenderEditable extends RenderBox
int placeholderIndex = 0;
int childIndex = 0;
RenderBox? child = firstChild;
final LinkedHashMap<Key, SemanticsNode> newChildCache = LinkedHashMap<Key, SemanticsNode>();
final Map<Key, SemanticsNode> newChildCache = <Key, SemanticsNode>{};
_cachedCombinedSemanticsInfos ??= combineSemanticsInfo(_semanticsInfo!);
for (final InlineSpanSemanticsInformation info in _cachedCombinedSemanticsInfos!) {
final TextSelection selection = TextSelection(
Expand Down
49 changes: 21 additions & 28 deletions packages/flutter/lib/src/rendering/mouse_tracker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/// @docImport 'binding.dart';
library;

import 'dart:collection' show LinkedHashMap;
import 'dart:ui';

import 'package:flutter/foundation.dart';
Expand All @@ -27,16 +26,13 @@ class _MouseState {
_MouseState({required PointerEvent initialEvent}) : _latestEvent = initialEvent;

// The list of annotations that contains this device.
//
// It uses [LinkedHashMap] to keep the insertion order.
LinkedHashMap<MouseTrackerAnnotation, Matrix4> get annotations => _annotations;
LinkedHashMap<MouseTrackerAnnotation, Matrix4> _annotations =
LinkedHashMap<MouseTrackerAnnotation, Matrix4>();
Map<MouseTrackerAnnotation, Matrix4> get annotations => _annotations;
Map<MouseTrackerAnnotation, Matrix4> _annotations = <MouseTrackerAnnotation, Matrix4>{};

LinkedHashMap<MouseTrackerAnnotation, Matrix4> replaceAnnotations(
LinkedHashMap<MouseTrackerAnnotation, Matrix4> value,
Map<MouseTrackerAnnotation, Matrix4> replaceAnnotations(
Map<MouseTrackerAnnotation, Matrix4> value,
) {
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> previous = _annotations;
final Map<MouseTrackerAnnotation, Matrix4> previous = _annotations;
_annotations = value;
return previous;
}
Expand Down Expand Up @@ -93,12 +89,12 @@ class _MouseTrackerUpdateDetails with Diagnosticable {
/// The annotations that the device is hovering before the update.
///
/// It is never null.
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> lastAnnotations;
final Map<MouseTrackerAnnotation, Matrix4> lastAnnotations;

/// The annotations that the device is hovering after the update.
///
/// It is never null.
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> nextAnnotations;
final Map<MouseTrackerAnnotation, Matrix4> nextAnnotations;

/// The last event that the device observed before the update.
///
Expand Down Expand Up @@ -232,11 +228,8 @@ class MouseTracker extends ChangeNotifier {
lastEvent.position != event.position;
}

LinkedHashMap<MouseTrackerAnnotation, Matrix4> _hitTestInViewResultToAnnotations(
HitTestResult result,
) {
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> annotations =
LinkedHashMap<MouseTrackerAnnotation, Matrix4>();
Map<MouseTrackerAnnotation, Matrix4> _hitTestInViewResultToAnnotations(HitTestResult result) {
final Map<MouseTrackerAnnotation, Matrix4> annotations = <MouseTrackerAnnotation, Matrix4>{};
for (final HitTestEntry entry in result.path) {
final Object target = entry.target;
if (target is MouseTrackerAnnotation) {
Expand All @@ -251,12 +244,12 @@ class MouseTracker extends ChangeNotifier {
//
// If the device is not connected or not a mouse, an empty map is returned
// without calling `hitTest`.
LinkedHashMap<MouseTrackerAnnotation, Matrix4> _findAnnotations(_MouseState state) {
Map<MouseTrackerAnnotation, Matrix4> _findAnnotations(_MouseState state) {
final Offset globalPosition = state.latestEvent.position;
final int device = state.device;
final int viewId = state.latestEvent.viewId;
if (!_mouseStates.containsKey(device)) {
return LinkedHashMap<MouseTrackerAnnotation, Matrix4>();
return <MouseTrackerAnnotation, Matrix4>{};
}

return _hitTestInViewResultToAnnotations(_hitTestInView(globalPosition, viewId));
Expand Down Expand Up @@ -341,12 +334,13 @@ class MouseTracker extends ChangeNotifier {
final _MouseState targetState = _mouseStates[device] ?? existingState!;

final PointerEvent lastEvent = targetState.replaceLatestEvent(event);
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> nextAnnotations =
final Map<MouseTrackerAnnotation, Matrix4> nextAnnotations =
event is PointerRemovedEvent
? LinkedHashMap<MouseTrackerAnnotation, Matrix4>()
? <MouseTrackerAnnotation, Matrix4>{}
: _hitTestInViewResultToAnnotations(result);
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> lastAnnotations = targetState
.replaceAnnotations(nextAnnotations);
final Map<MouseTrackerAnnotation, Matrix4> lastAnnotations = targetState.replaceAnnotations(
nextAnnotations,
);

_handleDeviceUpdate(
_MouseTrackerUpdateDetails.byPointerEvent(
Expand Down Expand Up @@ -374,11 +368,10 @@ class MouseTracker extends ChangeNotifier {
_deviceUpdatePhase(() {
for (final _MouseState dirtyState in _mouseStates.values) {
final PointerEvent lastEvent = dirtyState.latestEvent;
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> nextAnnotations = _findAnnotations(
dirtyState,
final Map<MouseTrackerAnnotation, Matrix4> nextAnnotations = _findAnnotations(dirtyState);
final Map<MouseTrackerAnnotation, Matrix4> lastAnnotations = dirtyState.replaceAnnotations(
nextAnnotations,
);
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> lastAnnotations = dirtyState
.replaceAnnotations(nextAnnotations);

_handleDeviceUpdate(
_MouseTrackerUpdateDetails.byNewFrame(
Expand Down Expand Up @@ -407,8 +400,8 @@ class MouseTracker extends ChangeNotifier {
static void _handleDeviceUpdateMouseEvents(_MouseTrackerUpdateDetails details) {
final PointerEvent latestEvent = details.latestEvent;

final LinkedHashMap<MouseTrackerAnnotation, Matrix4> lastAnnotations = details.lastAnnotations;
final LinkedHashMap<MouseTrackerAnnotation, Matrix4> nextAnnotations = details.nextAnnotations;
final Map<MouseTrackerAnnotation, Matrix4> lastAnnotations = details.lastAnnotations;
final Map<MouseTrackerAnnotation, Matrix4> nextAnnotations = details.nextAnnotations;

// Order is important for mouse event callbacks. The
// `_hitTestInViewResultToAnnotations` returns annotations in the visual order
Expand Down
5 changes: 2 additions & 3 deletions packages/flutter/lib/src/rendering/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
/// @docImport 'editable.dart';
library;

import 'dart:collection';
import 'dart:math' as math;
import 'dart:ui'
as ui
Expand Down Expand Up @@ -1268,7 +1267,7 @@ class RenderParagraph extends RenderBox
// can be re-used when [assembleSemanticsNode] is called again. This ensures
// stable ids for the [SemanticsNode]s of [TextSpan]s across
// [assembleSemanticsNode] invocations.
LinkedHashMap<Key, SemanticsNode>? _cachedChildNodes;
Map<Key, SemanticsNode>? _cachedChildNodes;

@override
void assembleSemanticsNode(
Expand All @@ -1285,7 +1284,7 @@ class RenderParagraph extends RenderBox
int placeholderIndex = 0;
int childIndex = 0;
RenderBox? child = firstChild;
final LinkedHashMap<Key, SemanticsNode> newChildCache = LinkedHashMap<Key, SemanticsNode>();
final Map<Key, SemanticsNode> newChildCache = <Key, SemanticsNode>{};
_cachedCombinedSemanticsInfos ??= combineSemanticsInfo(_semanticsInfo!);
for (final InlineSpanSemanticsInformation info in _cachedCombinedSemanticsInfos!) {
final TextSelection selection = TextSelection(
Expand Down